GinSoul 2015-05-23 07:32 采纳率: 0%
浏览 798

c++,pthread合并ppm图片

程序作用:
1. 创建4个线程,读取4张PPM图片(都是350*350),合并生成一张PPM图片(700*700)。
2. 改写成 创建进程(fork),读取4张PPM图片(都是350*350),合并生成一张PPM图片(700*700)。
我写的代码如下,不知为何只能显示一张图片:


#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <sys/wait.h>
#include <pthread.h>

using namespace std;

pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;

struct pixel
{
    char r;
    char g;
    char b;
};
pixel pp[350*350][4];

ifstream fin;
ofstream fout;

void *CreateImage(void *num)
{
    long i = (long)num;
    cout << i << endl;
    int position=18;
    char filename[20];
    char line1[100];
    char line2[100];
    char line3[100];
    char line4[100];
    int count = 0;

    cout << "file name: ";
    cin >> filename;

    fin.open(filename, ios::out | ios::binary);
    if (!fin.good())
    {
        cout << "bad file!\n";
    }

    fin >> line1 >> line2 >> line3 >> line4;
    fin.ignore();
    fin.ignore();

    for (int m = 0; m < 350 * 350; m++)
    {
        fin.read((char*)&pp[m][i], sizeof(pixel));
    }
    fin.close();

    for (int j = 0; j < 350; j++)
    {
    /*
    for(row =0; row < x; row++) // image 1 and image 2
    {
        fout.seekp(18*sizeof(char),ios_base::beg); //ignore header
        fout.seekp((row*(y*2*3))*sizeof(char),ios_base::cur);//to go current row
        for(col=0; col < y*3; col++)
        {
            fin1.read((char *)&tmp,sizeof(char));
            fout.write((const char *)&tmp,sizeof(char));
        }
        for(col=0; col < y*3; col++)
        {
            fin2.read((char *)&tmp,sizeof(char));
            fout.write((const char *)&tmp,sizeof(char));
        }
    }
    */
        if (i == 0)
            fout.seekp(position + (sizeof(pixel) * 350 * j * 2), ios::beg);

        if (i == 1)
            fout.seekp(position + 350 * sizeof(pixel) + (sizeof(pixel) * 350 * j * 2), ios::beg);
            //fout.seekp(position + , ios::beg);

        if (i==2)
            fout.seekp(position+(sizeof(pixel)*350*j*2)+700*350*sizeof(pixel),ios::beg);
        if (i==3)
            fout.seekp(position+350*sizeof(pixel)+(sizeof(pixel)*350*j*2)+700*350*sizeof(pixel),ios::beg);

        for (int n = 0; n < 350; n++)
            fout.write((char*) &pp[(n + count)][i], sizeof(pixel));

        count+=350;
    }

    fout.close();
}

int main()
{
    pthread_t pt[4];
    fout.open("newImage.ppm");
    if (!fout.good())
    {
        cout << "bad output file!\n";
        exit(0);
    }

    fout << "P6" << endl;
    fout << "#." << endl;
    fout << "700 700" << endl;
    fout << "255" << endl;   // these 4 lines are the head information of a ppm figure.

    for (int i = 0; i < 4; i++)
    {
        pthread_mutex_lock(&counter_mutex);
        pthread_create(&pt[i], NULL, CreateImage, (void*)i);
        pthread_mutex_unlock(&counter_mutex);
        //pthread_join(pt[i], NULL);

    }

    pthread_exit( NULL );  
    /*
    for(int j = 0; j < 4; j++)
    {
        pthread_join(pt[j], NULL);
    }
    */
    return 0;
}

  • 写回答

1条回答 默认 最新

  • ChatGPTᴼᴾᴱᴺᴬᴵ 2023-05-27 15:37
    关注

    该回答引用ChatGPT-3.5,仅供参考,不保证完全正确

    您的代码中存在一些问题,导致只能显示一张图片。以下是我对代码进行了一些修正的版本:

    #include <iostream>
    #include <fstream>
    #include <stdlib.h>
    #include <sys/wait.h>
    #include <pthread.h>
    
    using namespace std;
    
    pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;
    
    struct pixel
    {
        char r;
        char g;
        char b;
    };
    pixel pp[350 * 350][4];
    
    ifstream fin;
    ofstream fout;
    
    void *CreateImage(void *num)
    {
        long i = (long)num;
        cout << i << endl;
        int position = 18;
        char filename[20];
    
        cout << "file name: ";
        cin >> filename;
    
        fin.open(filename, ios::binary);
        if (!fin.good())
        {
            cout << "bad file!\n";
        }
    
        char line[100];
        fin.getline(line, sizeof(line)); // read and ignore the first line
        fin.getline(line, sizeof(line)); // read and ignore the second line
        fin.getline(line, sizeof(line)); // read and ignore the third line
    
        for (int m = 0; m < 350 * 350; m++)
        {
            fin.read((char *)&pp[m][i], sizeof(pixel));
        }
        fin.close();
    
        for (int j = 0; j < 350; j++)
        {
            if (i == 0)
                fout.seekp(position + (sizeof(pixel) * 350 * j * 2), ios::beg);
    
            if (i == 1)
                fout.seekp(position + 350 * sizeof(pixel) + (sizeof(pixel) * 350 * j * 2), ios::beg);
    
            if (i == 2)
                fout.seekp(position + (sizeof(pixel) * 350 * j * 2) + 700 * 350 * sizeof(pixel), ios::beg);
    
            if (i == 3)
                fout.seekp(position + 350 * sizeof(pixel) + (sizeof(pixel) * 350 * j * 2) + 700 * 350 * sizeof(pixel), ios::beg);
    
            for (int n = 0; n < 350; n++)
                fout.write((char *)&pp[(n + j * 350)][i], sizeof(pixel));
        }
    }
    
    int main()
    {
        pthread_t pt[4];
        fout.open("newImage.ppm", ios::binary);
        if (!fout.good())
        {
            cout << "bad output file!\n";
            exit(0);
        }
    
        fout << "P6" << endl;
        fout << "#." << endl;
        fout << "700 700" << endl;
        fout << "255" << endl; // these 4 lines are the head information of a ppm figure.
    
        for (int i = 0; i < 4; i++)
        {
            pthread_mutex_lock(&counter_mutex);
            pthread_create(&pt[i], NULL, CreateImage, (void *)i);
            pthread_mutex_unlock(&counter_mutex);
        }
    
        for (int j = 0; j < 4; j++)
        {
            pthread_join(pt[j], NULL);
        }
    
        fout.close();
    
        return 0;
    }
    

    请注意以下几点:

    1. 修复了文件读取的错误。在ifstream打开文件时,使用了错误的文件打开模式ios::out,应改为ios::binary
    2. 修改了对文件头信息的读取方式。在CreateImage函数中,

    读取文件头信息的代码有问题,现在使用getline函数来读取并忽略前三行。
    3. 修正了像素写入的错误。在循环写入像素数据时,应该根据当前行的索引j来计算在pp数组中的偏移量。
    4. 将文件的打开模式改为ios::binary,以二进制模式打开文件进行读写。

    这样修改后,程序应该能够正确地合并四张PPM图片并生成新的PPM图片。

    评论

报告相同问题?

悬赏问题

  • ¥15 oracle集群安装出bug
  • ¥15 关于#python#的问题:自动化测试
  • ¥20 问题请教!vue项目关于Nginx配置nonce安全策略的问题
  • ¥15 教务系统账号被盗号如何追溯设备
  • ¥20 delta降尺度方法,未来数据怎么降尺度
  • ¥15 c# 使用NPOI快速将datatable数据导入excel中指定sheet,要求快速高效
  • ¥15 再不同版本的系统上,TCP传输速度不一致
  • ¥15 高德地图2.0 版本点聚合中Marker的位置无法实时更新,如何解决呢?
  • ¥15 DIFY API Endpoint 问题。
  • ¥20 sub地址DHCP问题