libpng 图像倒置

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
87
88
89
90
91
92
93
94
95
96
97
98
99
#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;
}

  

posted on   lydstory  阅读(1)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
历史上的今天:
2023-02-01 杭州天谷信息电子章子
2023-02-01 icepdf
2022-02-01 中国红歌在线
2018-02-01 智能家居

导航

< 2025年3月 >
23 24 25 26 27 28 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 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示