1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
#include <SDL.h>
#include <time.h>
#include <png.h>
#include <string>
#include <iostream>
using namespace std;
Uint32 getPixel(SDL_Surface *surface, int x, int y)
{
int bpp = surface->format->BytesPerPixel;
/* Here p is the address to the pixel we want to retrieve */
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
switch(bpp) {
case 1:
return *p;
case 2:
return *(Uint16 *)p;
case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
return p[0] << 16 | p[1] << 8 | p[2];
else
return p[0] | p[1] << 8 | p[2] << 16;
case 4:
return *(Uint32 *)p;
default:
return 0; /* shouldn't happen, but avoids warnings */
}
}
bool saveAsPNG(SDL_Surface* toSave, string fileName)
{
FILE* file = fopen(fileName.c_str(), "wb");
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
if(!png_ptr)
{
fclose(file);
return false;
}
png_infop png_info = png_create_info_struct(png_ptr);
if(!png_info)
{
png_destroy_write_struct(&png_ptr, &png_info);
fclose(file);
return false;
}
if(setjmp(png_ptr->jmpbuf))
{
png_destroy_write_struct(&png_ptr, &png_info);
fclose(file);
return false;
}
/* données de l'image */
png_init_io(png_ptr, file);
// type de compression
png_set_compression_level(png_ptr, Z_BEST_SPEED);
// infos de l'image
png_set_IHDR(png_ptr, png_info, static_cast<png_uint_32>(toSave->w),
static_cast<png_uint_32>(toSave->h), 8,
PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
// date de création
png_time modtime;
png_convert_from_time_t(&modtime, time(NULL));
png_set_tIME(png_ptr, png_info, &modtime);
// commentaires de l'image
png_text text[6];
text[0].key = "Title";
text[0].text = "";
text[0].compression = PNG_TEXT_COMPRESSION_NONE;
text[1].key = "Author";
text[1].text = "";
text[1].compression = PNG_TEXT_COMPRESSION_NONE;
text[2].key = "Description";
text[2].text = "";
text[2].compression = PNG_TEXT_COMPRESSION_NONE;
text[3].key = "Copyright";
text[3].text = "";
text[3].compression = PNG_TEXT_COMPRESSION_NONE;
text[4].key = "E-mail";
text[4].text = "";
text[4].compression = PNG_TEXT_COMPRESSION_NONE;
text[5].key = "Url";
text[5].text = "";
text[5].compression = PNG_TEXT_COMPRESSION_NONE;
png_set_text(png_ptr, png_info, text, 6);
/* écriture de l'image */
png_write_info(png_ptr, png_info);
png_byte* line;
line = new png_byte[toSave->w * 3];
for(int i = 0; i < 480; ++i)
{
for(int p = 0, j = 0; j < toSave->w; ++j)
{
// extraction du pixel de la SDL_Surface*
Uint32 pixel = getPixel(toSave, j, i);
// extraction de chaque composante et écriture du pixel dans la ligne du png
line[p++] = pixel>>16;
line[p++] = pixel>>8;
line[p++] = pixel;
}
// écriture de la ligne dans le fichier
png_write_row(png_ptr, line);
}
delete[] line;
png_write_end(png_ptr, png_info);
png_destroy_write_struct(&png_ptr, &png_info);
fclose(file);
return true;
} |
Partager