FreeImage转换图像格式

freeimage 开源库 在C++ 转换图像格式

前言

​ 今天工作遇到的情况: 需要将32位深度BMP图像转换为8位图像并将白色背景设为透明

开始尝试用GDI+进行操作,发现只能将32位转8位,透明色无法修改,需要自己将写入调色板,并将RGB修改为调色板索引

后来网上搜图像处理库,无意中发现了 这个 Free_Image 的开源库

官网:https://freeimage.sourceforge.io/

文档/dll下载: https://freeimage.sourceforge.io/download.html

使用方式

​ 下载后,将FreeImage.lib 导入工程, 调用时引用FreeImage.h ,运行时将FreeImage.dll放到运行目录

实例代码

项目是C++的

 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
// ImageFactory.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <Windows.h>
#include <gdiplus.h>
#include <FreeImage.h>

using namespace std;

void bmp2PNG8(const char* bmp_fileName, const char* save_fileName);
void bmp2GIF8(const char* bmp_fileName, const char* save_fileName);


int main()
{
    //初始化 FreeImage
    FreeImage_Initialise();
    //测试函数
    bmp2PNG8("test.bmp","test1.png");
    bmp2GIF8("test.bmp", "test1.gif");
   
    //释放 FreeImage
    FreeImage_DeInitialise();
    
    return 0;
}

void bmp2PNG8(const char* bmp_fileName, const char* save_fileName)
{
    FIBITMAP* hDIB24bpp = FreeImage_Load(FIF_BMP, bmp_fileName, 0);
    if (hDIB24bpp) {
        FIBITMAP* res = FreeImage_Rescale(hDIB24bpp, 60, 40);

        // color-quantize 24bpp (results in a 8bpp bitmap to set transparency)
        FIBITMAP* hDIB8bpp = FreeImage_ColorQuantize(res, FIQ_WUQUANT);
        // 读取调色板并进行修改
        RGBQUAD* Palette = FreeImage_GetPalette(hDIB8bpp);
        BYTE Transparency[256];
        for (unsigned i = 0; i < 256; i++) {
            Transparency[i] = 0xFF;
            //判断调色板中RGB 白色时, 修改为透明色
            if (Palette[i].rgbGreen == 0xff && Palette[i].rgbBlue == 0xff && Palette[i].rgbRed == 0xff) {
                Transparency[i] = 0x00;
            }
        }

        //设置调色板
        FreeImage_SetTransparencyTable(hDIB8bpp, Transparency, 256);
        //保存图像
        FreeImage_Save(FIF_PNG, hDIB8bpp, save_fileName, 0);
        FreeImage_Unload(hDIB24bpp);
        FreeImage_Unload(hDIB8bpp);
        FreeImage_Unload(res);
    }
    else
    {
        cout << "读取错误" << endl;
    }
}


void bmp2GIF8(const char* bmp_fileName, const char* save_fileName)
{
    FIBITMAP* hDIB24bpp = FreeImage_Load(FIF_BMP, bmp_fileName, 0);
    if (hDIB24bpp) {
        FIBITMAP* res = FreeImage_Rescale(hDIB24bpp, 1600, 800);

        // color-quantize 24bpp (results in a 8bpp bitmap to set transparency)
        FIBITMAP* hDIB8bpp = FreeImage_ColorQuantize(res, FIQ_WUQUANT);

        // 读取调色板并进行修改
        RGBQUAD* Palette = FreeImage_GetPalette(hDIB8bpp);
        BYTE Transparency[256];
        for (unsigned i = 0; i < 256; i++) {
            Transparency[i] = 0xFF;
            //判断调色板中RGB 白色时, 修改为透明色
            if (Palette[i].rgbGreen == 0xff && Palette[i].rgbBlue == 0xff && Palette[i].rgbRed == 0xff) {
                Transparency[i] = 0x00;
            }
        }

        //设置调色板
        FreeImage_SetTransparencyTable(hDIB8bpp, Transparency, 256);


        //保存图像
        FreeImage_Save(FIF_GIF, hDIB8bpp, save_fileName, 0);
        FreeImage_Unload(hDIB24bpp);
        FreeImage_Unload(hDIB8bpp);
        FreeImage_Unload(res);
    }
    else
    {
        cout << "读取错误" << endl;
    }
}

相关函数说明

  1. FreeImage_Initialise 初始化DLL 必须调用
  2. FreeImage_DeInitialise 释放DLL 必须调用
  3. FreeImage_Load 从文件加载图像
  4. FreeImage_Rescale 图像缩放
  5. FreeImage_ColorQuantize RGB转索引图像
  6. FreeImage_GetPalette 获取调色板
  7. FreeImage_SetTransparencyTable 设置调色板
  8. FreeImage_Save 保存图像
  9. FreeImage_Unload 释放加载的图像

效果

原图

gif

test1

png

test1