我在玩文件时遇到了一些麻烦。这是我想要完成的。我试图通过取蓝色值的倒数(每三个值)来过滤PPM图像。我可以成功打开和写入文件,但我遇到了一些问题。在我的while(myfile.good())循环中,我认为只有最后3个数字被分配给变量r,g和b。我要做的是将每个第一个(三个)值分配给变量r,每个第二个值分配给g,每个第三个值分配给b。但是,我想取255 - 当前的b值,并将其设置为要应用于过滤器的新b值。我是否必须制作3个单独的文件(每个变量1个),然后将它们全部打开以将它们写入4个文件中作为最终副本?或者有没有办法将它们全部复制并将其分配给变量?任何帮助深表感谢。我是c ++的新手所以请原谅我。谢谢你的帮助。
我尝试使用的值示例:http://imgur.com/H6EDFIq
#include <iostream>
#include <cmath>
#include <fstream>
#include <cstdlib>
using namespace std;
int main()
{
char filename[50];
ifstream myfile;
cin.getline(filename, 50);
myfile.open(filename);
if(!myfile.is_open())
{
cout << "File cannot load.";
}
char r [50];
char g [50];
char b [50];
myfile >> r >> g >> b;
while (myfile.good())
{
myfile >> r >> g >> b;
}
myfile.close();
ofstream myfile2;
myfile2.open(filename);
//this is just to test to see what gets written onto the file
//for (int a=0; a<20; a++)
//{
// ** Is this even allowed?? int r = 255 - r;
//myfile2 << r << " " << g << " " << b;
//}
myfile2.close();
return 0;
}
答案 0 :(得分:0)
您需要检查.ppm图像的第一行.ppm标题。检查.ppm幻数,P3或P6,你需要检查。第二行是图像的尺寸,因此您也需要考虑到这一点。
这是我之前的工作,所以你可以得到一个想法。它可能不会立即起作用,所以只需给它一个阅读。
#include <iostream>
#include <fstream>
#include <sstream>
#include <exception>
int main() {
std::string filename = //whatever your file name is
std::ifstream input(filename.c_str(), std::ios::in | std::ios::binary);
if (input.is_open()) {
std::string line;
std::getline(input, line);
if (line != "P6" || line != "P3" ) { //you're going to want to check if you're using P3 or P6
//print out errors
}
std::stringstream image_dimensions(line);
try {
image_dimensions >> w //your width variable if you want to store it here
image_dimensions >> h //your height variable if you want to store it here
} catch (std::exception &e) {
std::cout << "Format error found in header " << e.what() << std::endl;
return;
}
int size = w*h;
std::getline(input, line);
std::stringstream max_value(line); //max colour value of the image
//you can initialise the vectors here if you want
std::vector<unsigned char> r;
std::vector<unsigned char> g;
std::vector<unsigned char> b;
//we know it max capacity so reserve that size for the vectors
r.reserve(size);
g.reserve(size);
b.reserve(size);
char read_rgb;
for (unsigned int i = 0; i < size; ++i) {
input.read(&read_rgb, 1);
r[i] = (unsigned char) read_rgb;
input.read(&read_rgb, 1);
g[i] = (unsigned char) read_rgb;
input.read(&read_rgb, 1);
b[i] = (unsigned char) read_rgb;
}
}
input.close();
}
您需要将r,g,b存储为您选择的数组。完成后,您可以遍历B数组并编辑它以应用过滤器,然后将其写入ppm文件。
此外,对于错误处理,您始终可以使用记事本或Notepad ++打开.ppm文件并读取图像。
答案 1 :(得分:0)
除非您特别需要将数据存储在内存中,否则在您阅读时将数据写入新文件会更简单。
这是一个读取带有8位颜色条目的P3 ppm的示例,按照您的请求反转蓝色通道,然后写入包含该数据的新文件。它没有进行大量的错误检查,但我不想让它比现有的更长。您将要添加自己的文件名提示等。
#include <iostream>
#include <string>
#include <fstream>
int main()
{
std::ifstream inFile("lena.ppm");
if(!inFile)
{
std::cerr << "Could not open input file.\n";
return -1;
}
std::string type;
std::string comment;
int width = 0, height = 0, colors = 0;
std::getline(inFile, type);
if(type != "P3")
{
std::cerr << "File is not a P3 format PPM.\n";
return -1;
}
if(inFile.peek() == '#')
{
std::getline(inFile, comment);
}
inFile >> width >> height >> colors;
std::ofstream outFile("lena2.ppm");
if(!outFile)
{
std::cerr << "Could not open output file.\n";
return -1;
}
outFile << type << "\n";
if(!comment.empty())
{
outFile << comment << "\n";
}
outFile << width << " " << height << "\n" << colors << "\n";
for(int y = 0; y < height; ++y)
{
for(int x = 0; x < width; ++x)
{
int r = 0, g = 0, b = 0;
if(!(inFile >> r >> g >> b))
{
std::cerr << "File ended early.\n";
return -1;
}
b = (255 - b);
if(x != 0 && !(x % 5)) //Keep lines under 70 columns per spec.
{
outFile << "\n";
}
outFile << r << " " << g << " " << b << " ";
}
outFile << "\n";
}
return 0;
}