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
| #include <iostream> #include <vector> #include <png.h>
void read_png_file(const char* file_name, std::vector<unsigned char>& image, unsigned& width, unsigned& height) { FILE *fp = fopen(file_name, "rb"); if (!fp) { std::cerr << "Error: Cannot open file " << file_name << std::endl; return; }
png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); if (!png) { std::cerr << "Error: Cannot create png read struct" << std::endl; fclose(fp); return; }
png_infop info = png_create_info_struct(png); if (!info) { std::cerr << "Error: Cannot create png info struct" << std::endl; png_destroy_read_struct(&png, nullptr, nullptr); fclose(fp); return; }
if (setjmp(png_jmpbuf(png))) { std::cerr << "Error: png jump buffer error" << std::endl; png_destroy_read_struct(&png, &info, nullptr); fclose(fp); return; }
png_init_io(png, fp); png_read_info(png, info);
width = png_get_image_width(png, info); height = png_get_image_height(png, info); png_byte color_type = png_get_color_type(png, info); png_byte bit_depth = png_get_bit_depth(png, info);
if (bit_depth == 16) png_set_strip_16(png);
if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png);
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_expand_gray_1_2_4_to_8(png);
if (png_get_valid(png, info, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png);
if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_PALETTE) png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png);
png_read_update_info(png, info);
image.resize(png_get_rowbytes(png, info) * height); std::vector<png_bytep> row_pointers(height);
for (unsigned i = 0; i < height; ++i) row_pointers[i] = image.data() + i * png_get_rowbytes(png, info);
png_read_image(png, row_pointers.data());
png_destroy_read_struct(&png, &info, nullptr); fclose(fp); }
int main() { const char* file_name = "../example.png"; std::vector<unsigned char> image; unsigned width, height;
read_png_file(file_name, image, width, height);
std::cout << "Image width: " << width << ", height: " << height << std::endl;
return 0; }
|