我有文件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++)
{
}
}
答案 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;
}