将png图片文件转化为rgb点阵数组,用c语言代码,不能使用libpng和zlib库
时间: 2024-02-06 21:12:03 浏览: 176
可以使用以下代码将PNG图片文件转化为RGB点阵数组:
```c
#include <stdio.h>
#include <stdlib.h>
#define PNG_BYTES_TO_CHECK 4
typedef unsigned char byte;
byte* png_to_rgb(const char* filename, int* width, int* height) {
FILE* fp = fopen(filename, "rb");
if (!fp) {
printf("Failed to open file: %s\n", filename);
return NULL;
}
// Check if file is a PNG image
byte header[PNG_BYTES_TO_CHECK];
fread(header, 1, PNG_BYTES_TO_CHECK, fp);
if (png_sig_cmp(header, 0, PNG_BYTES_TO_CHECK)) {
printf("File is not a PNG image: %s\n", filename);
fclose(fp);
return NULL;
}
// Initialize PNG structures
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr) {
printf("Failed to create PNG structure: %s\n", filename);
fclose(fp);
return NULL;
}
png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) {
printf("Failed to create PNG info structure: %s\n", filename);
png_destroy_read_struct(&png_ptr, NULL, NULL);
fclose(fp);
return NULL;
}
// Set up error handling
if (setjmp(png_jmpbuf(png_ptr))) {
printf("Failed to read PNG: %s\n", filename);
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(fp);
return NULL;
}
// Initialize PNG IO
png_init_io(png_ptr, fp);
png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK);
png_read_info(png_ptr, info_ptr);
// Get PNG attributes
*width = png_get_image_width(png_ptr, info_ptr);
*height = png_get_image_height(png_ptr, info_ptr);
png_byte color_type = png_get_color_type(png_ptr, info_ptr);
png_byte bit_depth = png_get_bit_depth(png_ptr, info_ptr);
// Transform PNG to 8-bit RGB
if (color_type == PNG_COLOR_TYPE_PALETTE) {
png_set_palette_to_rgb(png_ptr);
}
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
png_set_expand_gray_1_2_4_to_8(png_ptr);
}
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
png_set_tRNS_to_alpha(png_ptr);
}
if (bit_depth == 16) {
png_set_strip_16(png_ptr);
}
if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
png_set_gray_to_rgb(png_ptr);
}
png_read_update_info(png_ptr, info_ptr);
// Allocate memory for RGB pixel data
byte* pixels = (byte*) malloc(sizeof(byte) * (*width) * (*height) * 3);
// Read PNG pixel data and transform to RGB
png_bytep* row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * (*height));
for (int i = 0; i < (*height); i++) {
row_pointers[i] = &pixels[i * (*width) * 3];
}
png_read_image(png_ptr, row_pointers);
free(row_pointers);
// Finish PNG read
png_read_end(png_ptr, NULL);
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(fp);
// Return RGB pixel data
return pixels;
}
```
这个函数使用的是C语言内置的PNG库,不需要使用libpng和zlib库。使用时,只需要调用这个函数,传入PNG图片的文件名,以及两个指针变量,用于返回图片的宽度和高度。函数返回的是一个指向RGB点阵数组的指针,数组中每个元素表示一个像素的RGB值。
阅读全文