#include <png.h>
#include <iostream>
#include <fstream>
void invertImageColors(const char* inputFilename, const char* outputFilename) {
FILE *fp = fopen(inputFilename, "rb");
if (!fp) {
std::cerr << "Failed to open input PNG file." << std::endl;
return;
}
// 读取PNG文件头
png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
png_infop info = png_create_info_struct(png);
if (setjmp(png_jmpbuf)) {
png_destroy_read_struct(&png, &info, NULL);
fclose(fp);
std::cerr << "Error during PNG read operation." << std::endl;
return;
}
png_init_io(png, fp);
png_read_info(png, info);
// 获取图像宽度、高度、颜色类型、位深度等
int width = png_get_image_width(png, info);
int height = png_get_image_height(png, info);
int color_type = png_get_color_type(png, info);
int bit_depth = png_get_bit_depth(png, info);
// 设置图像类型:确保图像格式是 RGB 或 RGBA 以便进行颜色反转
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_gray_1_2_4_to_8(png);
}
if (png_get_valid(png, info, PNG_INFO_tRNS)) {
png_set_tRNS_to_alpha(png);
}
// 读取图像数据
png_read_update_info(png, info);
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, info));
}
png_read_png(png, info, PNG_TRANSFORM_IDENTITY, NULL);
// 对每个像素进行颜色反转
for (int y = 0; y < height; y++) {
png_bytep row = row_pointers[y];
for (int x = 0; x < width; x++) {
png_bytep px = &(row[x * 4]); // 假设是 RGBA 图像
px[0] = 255 - px[0]; // Red channel
px[1] = 255 - px[1]; // Green channel
px[2] = 255 - px[2]; // Blue channel
if (color_type == PNG_COLOR_TYPE_RGBA) {
px[3] = 255 - px[3]; // Alpha channel (optional)
}
}
}
// 写入新的 PNG 文件
FILE *out_fp = fopen(outputFilename, "wb");
if (!out_fp) {
std::cerr << "Failed to open output PNG file." << std::endl;
return;
}
png_structp out_png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
png_infop out_info = png_create_info_struct(out_png);
png_init_io(out_png, out_fp);
png_set_IHDR(out_png, out_info, width, height, bit_depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
png_write_info(out_png, out_info);
png_write_png(out_png, out_info, PNG_TRANSFORM_IDENTITY, NULL);
// 清理资源
fclose(out_fp);
for (int y = 0; y < height; y++) {
free(row_pointers[y]);
}
free(row_pointers);
png_destroy_read_struct(&png, &info, NULL);
png_destroy_write_struct(&out_png, &out_info);
fclose(fp);
std::cout << "Image inversion completed and saved to " << outputFilename << std::endl;
}
int main() {
const char* inputFilename = "input.png";
const char* outputFilename = "output_inverted.png";
invertImageColors(inputFilename, outputFilename);
return 0;
}