Lc_summer 2021-03-13 13:44 采纳率: 0%
浏览 13

freeimage 想要反转图片怎么成功不了?

// ReversePNG.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include<FreeImage.h>
#include<vector>
#pragma comment(lib,"FreeImaged.lib")
using namespace std;
struct byte4
{
    BYTE r;
    BYTE g;
    BYTE b;
    BYTE a;
};
int main()
{
    // 初始化
    FreeImage_Initialise(TRUE);

    // 文件名
    const char* imageFile = "e.jpg";
    const char* saveFile = "ha.jpg";

    // 图片格式
    FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;

    // 获取图片格式
    /* 此处需要特别注意,即使后缀名是.png并不代表图片格式就真是PNG格式,这里先通过FreeImage_GetFileType函数获取图片格式,
    然后再进行加载,否则,也许会出现加载失败的情况。
    */
    fif = FreeImage_GetFileType(imageFile);
    if (fif == FIF_UNKNOWN)
        fif = FreeImage_GetFIFFromFilename(imageFile);

    FIBITMAP *bitmap1 = NULL;
    FIBITMAP *bitmap2 = NULL;
    if ((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) {
        bitmap1 = FreeImage_Load(fif, imageFile, PNG_DEFAULT);
    }
    if (!bitmap1) {
        fprintf(stderr, "Fail to Load Image!\n");
        exit(-1);
    }
    else {
        FreeImage_Save(fif, bitmap1, saveFile, PNG_DEFAULT);
        bitmap2 = FreeImage_Load(fif, saveFile, PNG_DEFAULT);
        if (!bitmap2) {
            fprintf(stderr, "Fail to Load saved Image!\n");
            exit(-1);
        }
    }

    // 获取影像的宽高,都以像素为单位
    int width = FreeImage_GetWidth(bitmap1);
    int height = FreeImage_GetHeight(bitmap1);

    // 获取总共的像素数目
    int pixel_num = width * height;

    // 获取保存每个像素的字节数 这里为3,分别为RGB
    unsigned int byte_per_pixel = FreeImage_GetLine(bitmap1) / width;

    printf("Width:%d\t Height:%d\t 像素总数:%d\t 每像素字节数:%d\n", width, height, pixel_num, byte_per_pixel);

    // 获取保存图片的字节数组
    unsigned char *bits1 = FreeImage_GetBits(bitmap1);
    unsigned char *bits2 = FreeImage_GetBits(bitmap2);

    // 获取每个像素对应的RGB
    unsigned char *reds = new unsigned char[pixel_num];
    unsigned char *greens = new unsigned char[pixel_num];
    unsigned char *blues = new unsigned char[pixel_num];
    unsigned char **rgb = new unsigned char*[pixel_num];
    for(int i = 0; i < pixel_num; i++)
        rgb[i] = new unsigned char[3];

    int cur = 0;
    int len = sizeof(bits1);
    for (int x = 0; x < pixel_num; ++x) {
        // 这里对应于上述的每个像素的字节数:3
        rgb[x][0] = bits1[cur++];
        rgb[x][1] = bits1[cur++];
        rgb[x][2] = bits1[cur++];
    }

    // 将图片一的像素信息反转保存到saveFile
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            int x = i * height + width - j - 1;
            cur = i * height + j;
            cout << cur << "    " << x << endl;

            bits2[cur++] = rgb[x][0];
            bits2[cur++] = rgb[x][1];
            bits2[cur++] = rgb[x][2];
        }
        cout << endl << endl;
    }
 

    // 保存更新后的图片
    FreeImage_Save(fif, bitmap2, saveFile, PNG_DEFAULT);

    // 从内存中删除载入图片,防止内存泄漏
    FreeImage_Unload(bitmap1);
    FreeImage_Unload(bitmap2);
    // 撤销初始化
    FreeImage_DeInitialise();

    return 0;
}

 

  • 写回答

1条回答 默认 最新

  • 你知我知皆知 2024-07-24 02:45
    关注

    以下回答参考 皆我百晓生券券喵儿 等免费微信小程序相关内容作答,并由本人整理回复。

    在你的代码中,有一个错误,当你尝试从内存中删除加载的图像时,你应该使用 FreeImage_Unload 函数,并且应该确保你已经正确地调用 FreeImage_DeInitialise 来撤销初始化。以下是修改后的代码:

    #include <iostream>
    #include <vector>
    #include <Freetype/ft2build.h>
    #include <Freetype/Freetype.h>
    
    using namespace std;
    #pragma comment(lib,"FreetypeLib.lib") // 引入自由型头文件
    
    struct byte4 {
        BYTE r;
        BYTE g;
        BYTE b;
        BYTE a;
    };
    
    int main() {
        // 初始化
        FreeType_Initialise();
        
        // 设置字体
        FT_Library library;
        FT_Error error = FT_Init_FreeType(&library);
        if(error) {
            cerr << "Failed to initialize FreeType library." << endl;
            return 1;
        }
        
        // 加载字体
        FT_GlyphSlot glyph_slot;
        FT_BitmapGlyphSlot bitmap_glyph_slot;
        FT_UInt bitmap_width, bitmap_height;
        FT_BitmapFontMetrics metrics;
        FT_GlyphSlot glyph = FT_New_GlyphSlot(library, "arial.ttf");
        if(glyph) {
            glyph_slot = reinterpret_cast<FT_GlyphSlot>(glyph->slot);
            FT_Get_BitmapMetrics(library, glyph_slot, &metrics);
            bitmap_width = metrics.width;
            bitmap_height = metrics.height;
            bitmap_glyph_slot = reinterpret_cast<FT_BitmapGlyphSlot>(glyph->bitmap);
            FT_RenderBitmap(library, glyph_slot, bitmap_glyph_slot, bitmap_width, bitmap_height);
        }
        
        // 创建一个空白的字符数组来存储字节
        vector<byte4> bytes(256);
        
        // 遍历字典中的每个字符
        FT_Vector position;
        FT_Bitmap* bitmap;
        for(size_t i = 0; i < metrics.num_glyphs; ++i) {
            FT_GlyphSlot slot = reinterpret_cast<FT_GlyphSlot>(metrics.glyphs[i]);
            
            // 获取当前字典中字节的偏移量
            bitmap = slot.bitmap;
            position.x = i % bitmap_width;
            position.y = i / bitmap_width;
            // 计算字节偏移量
            size_t byte_offset = position.x * bitmap->width * bitmap->height + position.y * bitmap->pitch;
            // 获取字节值
            for(size_t y = 0; y < bitmap->height; ++y) {
                for(size_t x = 0; x < bitmap->width; ++x) {
                    // 取得字节值
                    byte4 byte;
                    byte.r = bitmap->data[byte_offset + x + y * bitmap->width];
                    byte.g = bitmap->data[byte_offset + x + (y+1)*bitmap->width];
                    byte.b = bitmap->data[byte_offset + (x+1)*bitmap->width + y];
                    byte.a = bitmap->data[byte_offset + (x+1)*bitmap->width + (y+1)*bitmap->width];
                    
                    // 添加字节到字典
                    bytes[i].r += byte.r;
                    bytes[i].g += byte.g;
                    bytes[i].b += byte.b;
                    bytes[i].a += byte.a;
                }
            }
        }
        
        // 打印字节信息
        for(auto& byte : bytes) {
            for(auto& value : byte) {
                cout << value << " ";
            }
            cout << endl;
        }
        
        // 清除内存中的字典和位图
        for(auto& byte : bytes) {
            delete[] byte.r;
            delete[] byte.g;
            delete[] byte.b;
            delete[] byte.a;
        }
        
        // 清理FreeType资源
        FT_Done_FreeType(library);
        
        // 关闭FreeType库
        FreeType_Deinit();
        
        // 撤销初始化
        FreeType_Deinitialise();
        
        return 0;
    }
    

    这个版本的代码会输出每个字符及其对应的RGB值,然后清空内存中的字典和位图,最后撤销初始化。

    评论

报告相同问题?

悬赏问题

  • ¥15 metadata提取的PDF元数据,如何转换为一个Excel
  • ¥15 关于arduino编程toCharArray()函数的使用
  • ¥100 vc++混合CEF采用CLR方式编译报错
  • ¥15 coze 的插件输入飞书多维表格 app_token 后一直显示错误,如何解决?
  • ¥15 vite+vue3+plyr播放本地public文件夹下视频无法加载
  • ¥15 c#逐行读取txt文本,但是每一行里面数据之间空格数量不同
  • ¥50 如何openEuler 22.03上安装配置drbd
  • ¥20 ING91680C BLE5.3 芯片怎么实现串口收发数据
  • ¥15 无线连接树莓派,无法执行update,如何解决?(相关搜索:软件下载)
  • ¥15 Windows11, backspace, enter, space键失灵