程序作用:
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;
}
该回答引用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;
}
请注意以下几点:
ifstream
打开文件时,使用了错误的文件打开模式ios::out
,应改为ios::binary
。CreateImage
函数中,读取文件头信息的代码有问题,现在使用getline
函数来读取并忽略前三行。
3. 修正了像素写入的错误。在循环写入像素数据时,应该根据当前行的索引j
来计算在pp
数组中的偏移量。
4. 将文件的打开模式改为ios::binary
,以二进制模式打开文件进行读写。
这样修改后,程序应该能够正确地合并四张PPM图片并生成新的PPM图片。