用C语言帮我写一个输入png图片,按照我的要求自动输出不同大小的png图片的函数
时间: 2024-02-17 22:01:38 浏览: 114
.net自动处理不同尺寸图片
4星 · 用户满意度95%
好的,以下是一个C语言的示例函数,可以实现输入PNG图片,自动输出不同大小的PNG图片的功能:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <png.h>
void resize_png(char* input_path, char* output_path, int* sizes, int num_sizes) {
// 打开输入文件
FILE* input_file = fopen(input_path, "rb");
if (!input_file) {
printf("Error: Failed to open input file: %s\n", input_path);
return;
}
// 读取PNG文件头
unsigned char header[8];
fread(header, 1, 8, input_file);
if (png_sig_cmp(header, 0, 8)) {
printf("Error: Input file is not a PNG file\n");
fclose(input_file);
return;
}
// 创建PNG读取结构体
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr) {
printf("Error: Failed to create PNG read structure\n");
fclose(input_file);
return;
}
// 创建PNG信息结构体
png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) {
printf("Error: Failed to create PNG info structure\n");
png_destroy_read_struct(&png_ptr, NULL, NULL);
fclose(input_file);
return;
}
// 设置PNG读取错误处理
if (setjmp(png_jmpbuf(png_ptr))) {
printf("Error: Failed to read PNG file\n");
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(input_file);
return;
}
// 初始化PNG读取
png_init_io(png_ptr, input_file);
png_set_sig_bytes(png_ptr, 8);
png_read_info(png_ptr, info_ptr);
// 获取PNG信息
png_uint_32 width = png_get_image_width(png_ptr, info_ptr);
png_uint_32 height = png_get_image_height(png_ptr, info_ptr);
int color_type = png_get_color_type(png_ptr, info_ptr);
int bit_depth = png_get_bit_depth(png_ptr, info_ptr);
// 设置PNG输出错误处理
if (setjmp(png_jmpbuf(png_ptr))) {
printf("Error: Failed to write PNG file\n");
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(input_file);
return;
}
// 遍历每个尺寸
for (int i = 0; i < num_sizes; i++) {
int size = sizes[i];
// 计算新的宽度和高度
png_uint_32 new_width, new_height;
if (width > height) {
new_width = size;
new_height = (int)(size * height / width);
} else {
new_height = size;
new_width = (int)(size * width / height);
}
// 创建PNG写入结构体
png_structp png_write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_write_ptr) {
printf("Error: Failed to create PNG write structure\n");
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(input_file);
return;
}
// 创建PNG信息结构体
png_infop png_write_info_ptr = png_create_info_struct(png_write_ptr);
if (!png_write_info_ptr) {
printf("Error: Failed to create PNG write info structure\n");
png_destroy_write_struct(&png_write_ptr, NULL);
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(input_file);
return;
}
// 打开输出文件
char output_filename[256];
sprintf(output_filename, "%s_%d.png", output_path, size);
FILE* output_file = fopen(output_filename, "wb");
if (!output_file) {
printf("Error: Failed to open output file: %s\n", output_filename);
png_destroy_write_struct(&png_write_ptr, &png_write_info_ptr);
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(input_file);
return;
}
// 设置PNG写入
png_init_io(png_write_ptr, output_file);
png_set_IHDR(png_write_ptr, png_write_info_ptr, new_width, new_height, bit_depth, color_type, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
png_write_info(png_write_ptr, png_write_info_ptr);
// 读取并写入PNG数据
png_bytep* row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * new_height);
for (int j = 0; j < new_height; j++) {
row_pointers[j] = (png_bytep)malloc(png_get_rowbytes(png_ptr, info_ptr));
}
png_read_image(png_ptr, row_pointers);
png_write_image(png_write_ptr, row_pointers);
// 释放内存并关闭文件
for (int j = 0; j < new_height; j++) {
free(row_pointers[j]);
}
free(row_pointers);
png_write_end(png_write_ptr, NULL);
png_destroy_write_struct(&png_write_ptr, &png_write_info_ptr);
fclose(output_file);
}
// 释放内存并关闭文件
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(input_file);
}
// 示例用法
int main() {
char* input_path = "example.png";
char* output_path = "example_resized";
int sizes[] = {100, 200, 300};
int num_sizes = 3;
resize_png(input_path, output_path, sizes, num_sizes);
return 0;
}
```
你可以将`input_path`替换为你的PNG图片路径,将`output_path`替换为你想要输出的文件名(不包含文件扩展名),并修改`sizes`数组以包含你需要的不同尺寸即可。
阅读全文