问题
I am building my first ever program in C++ over and over again.
The program is intended to create a picture, a gradient - with parameters of height h
, width l
, in pixels, and 4 parameters of density Da, Db, Dc, Dd
.
This gradient is produced by '1 bit' pixels: they are black or white - and by the simplest error-diffusion algorithm (so-called "naive" sometimes),
>> push the error on the next pixel of the line.
After having performed an optimization (deque
instead of vector
allows bigger images to be created for ex.), I am stuck with a problem that I cannot solve for now:
My pixel values being stored in a deque
, how do I transport them into a bitmap file?
I tried to understand the EasyBMP
library but I couldn't find the solution.
In my code, you can see line 33
that I tried (unsuccessfully) to make a .PBM header (Portable Bit Map)
Actually, I'd like to copy the values of my deque <int> dequeA;
(line 30)
to a .BMP
file or any other raster file-format, instead of in a .txt
file like it happens line 72!
Here's my code, and a nice picture of what it makes :
#include <iostream>
#include <fstream>
#include <vector>
#include <deque>
#include <iterator>
#include <cstdlib>
#include <string>
#include <sstream>
using namespace std;
// constant values
double Da=1; //densities
double Db=0.5;
double Dc=0.5;
double Dd=0;
double l = 999; //width & height => L = l+1 /// 999 = 1000 pixels
double h = 999;
//double u = 1; // UNIT
double D = 0; // GAMMA
double E = 0; // ERROR LOCAL
vector <double> F; // ERROR DYNAMIC
int main ()
{
// vector
deque <int> dequeA;
F.push_back (0);
//dequeA.push_back (2); //FAKE PBM header (old)
//dequeA.push_back (l+1);
//dequeA.push_back (h+1);
//dequeA.push_back (1);
float a = 0;
float b = 0; // Local variables
double IO = 0; // variable I/O
while (a<l+1, b<h+1){
//values for given a & b
double DL = Da-Da*(b/h)+Dc*(b/h);
double DR = Db-Db*(b/h)+Dd*(b/h);
double D = DL-DL*(a/l)+DR*(a/l); //GAMMA
if (E+0-D<=-0.5) {
dequeA.push_back(1);
IO = 1;
}
else {
dequeA.push_back(0);
IO = 0;
}
E = E+IO-D;
F.push_back(E);
// next pixel & next line
a++;
if (a>l) {
a = 0;
b = b++;
E = 0;
F.clear();
}
}
//export values to .txt file
ofstream output_file("./test.txt");
ostream_iterator<int> output_iterator(output_file, "\n");
copy(dequeA.begin(), dequeA.end(), output_iterator);
dequeA.clear();
}
回答1:
PBM files are very easy to create and should suffice for your purpose. No need to use an external library.
A problem in your original code was that you were storing both the PBM metadata and the actual image data in the same dequeA
. Don't do that. Mixing data like this makes your program hard to understand and maintain.
You can create a valid PBM file by slightly adjusting the code writing the file:
ofstream output_file("./test.ppm");
// write file header
output_file << "P1\n" << (l+1) << " " << (h+1) << "\n";
//write image data
ostream_iterator<int> output_iterator(output_file, "\n");
copy(dequeA.begin(), dequeA.end(), output_iterator);
The resulting PPM file works fine with Gimp.
Writing to a BMP or TGA file works basically the same - you first write a header, followed by the actual data. The main difference is that those file formats are binary files, so the file I/O looks a bit different, and the header and image data formats are slightly more complicated. But still, both formats are quite simple and easy to write even without using a library.
来源:https://stackoverflow.com/questions/17583825/c-how-to-create-a-large-bitmap-from-a-datalist-stored-in-a-deque