如何编辑图像的值

How to edit values of images

本文关键字:图像 编辑 何编辑      更新时间:2023-10-16

我在处理文件时遇到了一些问题。以下是我正在努力实现的目标。我试图通过取蓝色值的倒数(每三个值一次)来过滤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;
}

除非您特别需要将数据存储在内存中,否则在读取数据时将数据写入新文件会更简单。

这里有一个示例,它读取具有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;
}

您需要检查.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或Notepad++打开.ppm文件并读取图像。