将pbm ascii保存到pbm binary c ++

时间:2013-11-20 06:05:37

标签: c++ image-processing

我有文件pbm P1(ascii)

P1
#Created by Venom 
2 2 
1 0 
0 1

我想将其转换为P4(pbm binary)。我怎么能这样做?

我有像素数组int

int pixel[HEIGHT][WIDTH];

我需要将它转换为二进制数组

for (int i =0; i < HEIGHT ; i++)
     {
         for (int j =0; j < WIDTH; j++)
         {

             }
}

2 个答案:

答案 0 :(得分:1)

这似乎适用于我能够找到的文件来测试它。

#include <iostream>
#include <fstream>
#include <string>
#include <vector>

struct PBM
{
    unsigned int width;
    unsigned int height;
    std::string comment;
    std::vector<std::vector<char>> data;

    bool ReadAscii(std::ifstream& f)
    {
        std::string id;
        if(!std::getline(f, id) || id != "P1")
        {
            return false;
        }
        if(f.peek() == '#' && !std::getline(f, comment))
        {
            return false;
        }
        if(!(f >> width >> height))
        {
            return false;
        }
        data.resize(height);
        int temp;
        for(size_t y = 0; y < data.size(); ++y)
        {
            data[y].resize(width);
            for(size_t x = 0; x < width; ++x)
            {
                if(!(f >> temp))
                {
                    return false;
                }
                data[y][x] = static_cast<char>(temp);
            }
        }
        return true;
    }

    bool WriteBinary(std::ofstream& f)
    {
        if(!(f << "P4\n"))
        {
            return false;
        }
        if(!comment.empty() && !(f << comment << "\n"))
        {
            return false;
        }
        if(!(f << width << " " << height << "\n"))
        {
            return false;
        }
        std::vector<char> linebits((width + (CHAR_BIT - 1)) / CHAR_BIT);
        for(size_t y = 0; y < data.size(); ++y)
        {
            std::fill(linebits.begin(), linebits.end(), 0);
            for(size_t x = 0; x < width; ++x)
            {
                const int byte_pos = x / CHAR_BIT;
                const int bit_pos = (CHAR_BIT - 1) - (x % CHAR_BIT);
                linebits[byte_pos] |= (data[y][x] << bit_pos);
            }
            if(!f.write(&linebits[0], linebits.size()))
            {
                return false;
            }
        }
        return true;
    }
};

int main(int argc, char * argv[])
{
    if(argc != 3)
    {
        std::cerr << "Usage: convertpbm <ascii filename> <binary filename>\n";
        return 0;
    }

    PBM pbm;

    std::ifstream inFile(argv[1]);
    if(!inFile)
    {
        std::cerr << "Could not open '" << argv[1] << "' for input!\n";
        return 0;
    }
    if(!pbm.ReadAscii(inFile))
    {
        std::cerr << "Error reading input file!\n";
    }

    std::ofstream outFile(argv[2], std::ios::binary);
    if(!outFile)
    {
        std::cerr << "Could not open '" << argv[1] << "' for output!\n";
        return 0;
    }
    if(!pbm.WriteBinary(outFile))
    {
        std::cerr << "Error writing output file!\n";
    }

    return 0;
}

答案 1 :(得分:0)

很抱歉等待,我的程序从ascii颜色转换为bpm ascii好,但是将此ascii转换为二进制文件时出现问题

#include <stdio.h>
#include <string>
#include <sstream>
#include <stdlib.h>
#include <conio.h>
#include <iostream>
#include <fstream>
#include <bitset>  
#include <vector>
#define WIDTH 512
#define HEIGHT 512

using namespace std;

typedef int array_type[WIDTH][HEIGHT] ;



void convertWithDithering(array_type& pixelgray)
{
    int oldpixel;
    int newpixel =0 ;
    int quant_error;

    for (int y = 0; y< HEIGHT; y++){
        for (int x = 0; x<WIDTH; x++){
                oldpixel = pixelgray[x][y];
                 newpixel  = (oldpixel > 128) ? 255 :0;
                 pixelgray[x][y] = newpixel;
                  quant_error  = oldpixel - newpixel;
                if (x+1 <WIDTH)
                    pixelgray[x+1][y]  =  pixelgray[x+1][y] + 7 * quant_error/16;
                if ((x-1 >0)&&(y+1<HEIGHT))
                pixelgray[x-1][y+1]  = pixelgray[x-1][y+1] + 3 * quant_error/16;
                if (y+1 <HEIGHT)
                pixelgray[x  ][y+1]=pixelgray[x  ][y+1]+  5 * quant_error/16;
                if ((x+1<0)&&(y+1<HEIGHT))
                 pixelgray[x+1][y+1] = pixelgray[x+1][y+1]+ 1 * quant_error/16;
        }
    }

    for (int y = 0; y< HEIGHT; y++){
        for (int x = 0; x<WIDTH; x++){
            if (pixelgray[x][y]==255) pixelgray[x][y] =0;
            else pixelgray[x][y] =1;
        }
    }
}

void readPPM(array_type& pixel, string filename)
{
    ifstream file(filename);
     string str;
    string img;
    int r, g, b;
    int currentstring = 0;

    int i =0, j =0;
    while (getline(file, str))
    {
        istringstream stringStream(str);
        if (currentstring> 3)
        {
            unsigned char c;
            while (stringStream >> c)
            {
                c>> r;
                stringStream >> r;
                stringStream >> g;
                stringStream >> b;

                int graycolor = (r+g+b)/3;
                pixel [j][i]=graycolor;

                if (i == 512)
                {
                    j++;
                    i=0;
                }

                    i++;
            }

        }

        currentstring ++;

    }
}

void writePBM (array_type& pixel)
{
    string type = "P4\n";
    string comment = "# Created by Venom\n";
    ostringstream oOStrStream;
    oOStrStream << type<< comment << WIDTH <<" "<< HEIGHT << "\n";

    convertWithDithering (pixel);

    ofstream outfile ("image.pbm");
    outfile << oOStrStream.str();

    vector<char> linebits((WIDTH + (CHAR_BIT - 1)) / CHAR_BIT);
    for (int i =0; i < HEIGHT ; i++)
     {

         fill(linebits.begin(), linebits.end(), 0);
         for (int j =0; j < WIDTH; j++)
         {

             const int byte_pos = j / CHAR_BIT;
             const int bit_pos = (CHAR_BIT - 1) - (j % CHAR_BIT);
             linebits[byte_pos]|=(pixel[i][j]<< bit_pos);

         }

        outfile.write(&linebits[0], linebits.size());

}

}
int main()
{
    static int pixel [HEIGHT][WIDTH];

    readPPM(pixel, "P3.ppm");
    writePBM (pixel);

     cout << "done" << endl;

    _getch();
    return 0;
}