I am trying to write some data to a PNG file using C++ with Visual Studio Express 2013 on Windows 7 64-bit. I understand that to do this, I need to use an external library,
The missing header file may be because you need to specify addition include directories as well to point to libpng's header files. It looks like you are probably linking correctly.
It's been a while since I've done this in visual studios, but there should be a field for this in the projects configuration.
Consider writing your file in NetPBM/PBMplus format as specified here. It is very easy and you don't need a library as the file is so straightforward. The Wikipedia article shows the format here.
Here is a simple example:
#include <stdio.h>
#include <stdlib.h>
int main(){
FILE *imageFile;
int x,y,pixel,height=100,width=256;
imageFile=fopen("image.pgm","wb");
if(imageFile==NULL){
perror("ERROR: Cannot open output file");
exit(EXIT_FAILURE);
}
fprintf(imageFile,"P5\n"); // P5 filetype
fprintf(imageFile,"%d %d\n",width,height); // dimensions
fprintf(imageFile,"255\n"); // Max pixel
/* Now write a greyscale ramp */
for(x=0;x<height;x++){
for(y=0;y<width;y++){
pixel=y;
fputc(pixel,imageFile);
}
}
fclose(imageFile);
}
Once you have the file as PBM/PGM frmat, use ImageMagick (here) to convert to PNG with a simple command like:
convert file.pgm file.png
LodePNG is as easy as you say. I've used it before as well. Just in case you change your mind and decide to encode the data you have into the right format (assuming it is BGRA
).. The following will convert the BGRA format to RGBA as required by lodepng..
std::vector<std::uint8_t> PngBuffer(ImageData.size());
for(std::int32_t I = 0; I < Height; ++I)
{
for(std::int32_t J = 0; J < Width; ++J)
{
std::size_t OldPos = (Height - I - 1) * (Width * 4) + 4 * J;
std::size_t NewPos = I * (Width * 4) + 4 * J;
PngBuffer[NewPos + 0] = ImageData[OldPos + 2]; //B is offset 2
PngBuffer[NewPos + 1] = ImageData[OldPos + 1]; //G is offset 1
PngBuffer[NewPos + 2] = ImageData[OldPos + 0]; //R is offset 0
PngBuffer[NewPos + 3] = ImageData[OldPos + 3]; //A is offset 3
}
}
std::vector<std::uint8_t> ImageBuffer;
lodepng::encode(ImageBuffer, PngBuffer, Width, Height);
lodepng::save_file(ImageBuffer, "SomeImage.png");