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; } |