linux C 使用libpng将png文件解码为bmp数组
时间: 2024-02-18 18:06:00 浏览: 396
使用libpng库将png文件解码为bmp数组的步骤如下:
1. 安装libpng库。在Ubuntu上可以使用以下命令安装:
```
sudo apt-get install libpng-dev
```
2. 编写C代码。下面是一个示例代码,可以将输入的png文件解码为bmp数组,并输出为另一个文件。
```c
#include <stdio.h>
#include <stdlib.h>
#include <png.h>
int main(int argc, char *argv[]) {
if (argc != 3) {
printf("Usage: %s input_file.png output_file.bmp\n", argv[0]);
return 1;
}
char *input_file = argv[1];
char *output_file = argv[2];
// 打开png文件
FILE *fp = fopen(input_file, "rb");
if (!fp) {
printf("Error opening file %s\n", input_file);
return 1;
}
// 读取png文件头信息
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr) {
printf("Error creating read struct\n");
fclose(fp);
return 1;
}
png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) {
printf("Error creating info struct\n");
fclose(fp);
png_destroy_read_struct(&png_ptr, NULL, NULL);
return 1;
}
if (setjmp(png_jmpbuf(png_ptr))) {
printf("Error during setjmp\n");
fclose(fp);
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return 1;
}
png_init_io(png_ptr, fp);
png_read_info(png_ptr, info_ptr);
// 获取png文件信息
int width = png_get_image_width(png_ptr, info_ptr);
int 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);
// 将png文件转换为bmp数组
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);
png_bytep *row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height);
for (int y = 0; y < height; y++) {
row_pointers[y] = (png_byte*) malloc(png_get_rowbytes(png_ptr, info_ptr));
}
png_read_image(png_ptr, row_pointers);
// 将bmp数组输出到文件
FILE *fout = fopen(output_file, "wb");
if (!fout) {
printf("Error opening output file %s\n", output_file);
fclose(fp);
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
for (int y = 0; y < height; y++)
free(row_pointers[y]);
free(row_pointers);
return 1;
}
fwrite("BM", 1, 2, fout);
int bmp_size = width * height * 3;
int bmp_offset = 54;
int file_size = bmp_offset + bmp_size;
fwrite(&file_size, 4, 1, fout);
fwrite("\0\0\0\0", 4, 1, fout);
fwrite(&bmp_offset, 4, 1, fout);
int header_size = 40;
int planes = 1;
int bits_per_pixel = 24;
int compression = 0;
int image_size = bmp_size;
int x_pixels_per_meter = 2835;
int y_pixels_per_meter = 2835;
int total_colors = 0;
int important_colors = 0;
fwrite(&header_size, 4, 1, fout);
fwrite(&width, 4, 1, fout);
fwrite(&height, 4, 1, fout);
fwrite(&planes, 2, 1, fout);
fwrite(&bits_per_pixel, 2, 1, fout);
fwrite(&compression, 4, 1, fout);
fwrite(&image_size, 4, 1, fout);
fwrite(&x_pixels_per_meter, 4, 1, fout);
fwrite(&y_pixels_per_meter, 4, 1, fout);
fwrite(&total_colors, 4, 1, fout);
fwrite(&important_colors, 4, 1, fout);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
png_byte *ptr = &row_pointers[y][x * 3];
fwrite(ptr + 2, 1, 1, fout);
fwrite(ptr + 1, 1, 1, fout);
fwrite(ptr, 1, 1, fout);
}
}
fclose(fout);
fclose(fp);
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
for (int y = 0; y < height; y++)
free(row_pointers[y]);
free(row_pointers);
return 0;
}
```
在终端中执行以下命令编译代码:
```
gcc png2bmp.c -o png2bmp -lpng
```
3. 执行程序。在终端中输入以下命令,将png文件转换为bmp数组:
```
./png2bmp input_file.png output_file.bmp
```
其中,'input_file.png'为需要转换的png文件名,'output_file.bmp'为输出的bmp文件名。执行成功后,会在当前目录下生成一个bmp文件。
阅读全文