I urgently need your help! I’m trying to use SDL_Surface’s pixel data to
save it in a PNG file. Unfortunately, it doesn’t matter what I try - the
output results in garbage. I just don’t get how to read out the necessary
data and to transform it to satisfy “png_write_image(…)”. Has anyone
already created a similar function to save a SDL_Surface as an PNG? Could
someone show me how to give Libpng the appropriate pixel data?
Many, many thanks in advance!
No!
I give you a piece of code which saves RAW RGB format to PNG:------------------------------------
// Write a PNG Image from RAW RGB format
//
// Parameters:
// [in] file png file
// [in] image_data raw image
// [in] width of image
// [in] height of image
//
char WritePNG(char *file, unsigned char *image_data, png_uint_32 width,
png_uint_32 height)
{
png_structp png_ptr;
png_infop info_ptr;
png_uint_32 i, rowbytes;
png_bytepp row_pointers;
// Open PNG file for writting
FILE *fp = fopen(file, “wb”);
if (!fp) return 4;
// Allocate basic libpng structures
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
if (!png_ptr) { fclose(fp); return 1; }
info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr)
{
png_destroy_write_struct(&png_ptr, 0);
fclose(fp); return 1;
}
// setjmp() must be called in every function
// that calls a PNG-reading libpng function
if (setjmp(png_ptr->jmpbuf))
{
png_destroy_write_struct(&png_ptr, &info_ptr);
fclose(fp); return 3;
}
png_init_io(png_ptr, fp);
// set the zlib compression level
png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
// write PNG info to structure
png_set_IHDR(png_ptr, info_ptr, width, height, 8,
PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
png_write_info(png_ptr, info_ptr);
// setjmp() must be called in every function
// that calls a PNG-writing libpng function
if (setjmp(png_ptr->jmpbuf))
{
png_destroy_write_struct(&png_ptr, &info_ptr);
fclose(fp); return 3;
}
// If color is BGR change to RGB
// png_set_bgr(png_ptr);
// Allocate pointers for each line
row_pointers = malloc(height * sizeof(png_bytep));
if (!row_pointers)
{
png_destroy_write_struct(&png_ptr, &info_ptr);
fclose(fp); return 1;
}
// how many bytes in each row
rowbytes = png_get_rowbytes(png_ptr, info_ptr);
// set the individual row_pointers to point at the correct offsets
for (i = 0; i < height; ++i) row_pointers[i] = image_data + i * rowbytes;
// now we can go ahead and just write the whole image
png_write_image(png_ptr, row_pointers);
png_write_end(png_ptr, 0);
png_destroy_write_struct(&png_ptr, &info_ptr);
free(row_pointers); fclose(fp); return 0;
}
returns 0 on success, or the error code (see the code for details)