FreeImage 生成带透明通道的GIF

主要方法:

  1. 加载图像及读取参数
    FreeImage_Load
    FreeImage_GetWidth
    FreeImage_GetHeight
    FreeImage_Allocate
    FreeImage_GetPixelColor
    FreeImage_SetPixelColor
  2. 保存GIF
    FreeImage_OpenMultiBitmap
    FreeImage_SetMetadata
    FreeImage_SetTagXX
    FreeImage_AppendPage
  3. GIF 透明模板
    FreeImage_ColorQuantize
    FreeImage_GetPalette
    FreeImage_SetTransparencyTable

这里需要注意的是,图像通道32位转24位时,不使用FreeImage_ConvertTo24Bits,而通过PNG透明通道进行数据复制,避免背景对后面生成透明表(FreeImage _SetTransparencyTable)造成干扰。此外,注意设置24位图的背景色,避免与表情区域颜色相近。

这里做了如下设置

// 蓝色 src_color.rgbRed = 0; src_color.rgbBlue = 255; src_color.rgbGreen = 0;
完整代码:

#include "FreeImagePlus.h"

#include <iostream>
using namespace std;

FIBITMAP* genhDIB8bpp(FIBITMAP* hDIB32bpp);

int main(int argc, char** argv[])
{
    FreeImage_Initialise(TRUE);
    // load source images
    FIBITMAP* hdib1 = FreeImage_Load(FIF_PNG, "img1.png", PNG_IGNOREGAMMA);
    FIBITMAP* hdib2 = FreeImage_Load(FIF_PNG, "img2.png", PNG_IGNOREGAMMA);
    FIBITMAP* hdib3 = FreeImage_Load(FIF_PNG, "img3.png", PNG_IGNOREGAMMA);

    if (NULL == hdib1 || NULL == hdib2 || NULL == hdib3)
    {
        cout << " load  image(png) error. \n";
        return -1;
    }

    int bpp1 = FreeImage_GetBPP(hdib1);
    int bpp2 = FreeImage_GetBPP(hdib2);
    int bpp3 = FreeImage_GetBPP(hdib3);

    int dib_type = FreeImage_GetImageType(hdib1);
    cout << "Type: " << dib_type << " " << FIT_BITMAP  << endl;
    cout << "BPP: " << bpp1 << " " << bpp2 << " " << bpp3 << endl;
    if (32 != bpp1 || 32 != bpp2 || 32 != bpp3)
        return -1;

    bool bMemoryCache = TRUE;

    FIMULTIBITMAP *multi = FreeImage_OpenMultiBitmap(FIF_GIF, "out.gif", TRUE, FALSE);
    int fps = 3;
    DWORD dwFrameTime = (DWORD)((1000.0f / fps) + 0.5f);

    cout << "gen hDIB8bpp " << endl;
    FIBITMAP* dib[3];
    dib[0] = genhDIB8bpp(hdib1);
    dib[1] = genhDIB8bpp(hdib2);
    dib[2] = genhDIB8bpp(hdib3);

    cout << "AppendPage" << endl;
    for (int i = 0; i < 3; i++ ){
        // clear any animation metadata used by this dib as we’ll adding our own ones
        FreeImage_SetMetadata(FIMD_ANIMATION, dib[i], NULL, NULL);
        // add animation tags to dib[i]
        FITAG *tag = FreeImage_CreateTag();
        if (tag) {
            FreeImage_SetTagKey(tag, "FrameTime");
            FreeImage_SetTagType(tag, FIDT_LONG);
            FreeImage_SetTagCount(tag, 1);
            FreeImage_SetTagLength(tag, 4);
            FreeImage_SetTagValue(tag, &dwFrameTime);
            FreeImage_SetMetadata(FIMD_ANIMATION, dib[i], FreeImage_GetTagKey(tag), tag);
            FreeImage_DeleteTag(tag);
        }
        FreeImage_AppendPage(multi, dib[i]);
//      FreeImage_Unload(dib[i]);
    }
    FreeImage_CloseMultiBitmap(multi);

    FreeImage_Unload(dib[0]);
    FreeImage_Unload(dib[1]);
    FreeImage_Unload(dib[2]);

    FreeImage_Unload(hdib1);
    FreeImage_Unload(hdib2);
    FreeImage_Unload(hdib3);

    FreeImage_DeInitialise();
    return 0;
}

FIBITMAP* genhDIB8bpp(FIBITMAP* hDIB32bpp)
{
    FIBITMAP* hDIB8bpp = NULL;
    int w = FreeImage_GetWidth(hDIB32bpp);
    int h = FreeImage_GetHeight(hDIB32bpp);

//  FIBITMAP *hDIB24bpp  = FreeImage_ConvertTo24Bits(hDIB32bpp);
    FIBITMAP *hDIB24bpp = FreeImage_Allocate(w, h, 24);
    for (int i = h - 1; i >= 0; i--)
        for (int j = 0; j < w; j++)
        {
            RGBQUAD src_color;
            FreeImage_GetPixelColor(hDIB32bpp, j, i, &src_color);
            if ( 255 == src_color.rgbReserved )
                FreeImage_SetPixelColor(hDIB24bpp, j, i, &src_color);
            else
            {
                src_color.rgbRed = 0;
                src_color.rgbBlue = 255; src_color.rgbGreen = 0;
                FreeImage_SetPixelColor(hDIB24bpp, j, i, &src_color);
            }
        }
    FreeImage_Save(FIF_JPEG, hDIB24bpp, "out.jpg");

    BYTE  Transparency[256];
    if (!hDIB8bpp)
        hDIB8bpp = FreeImage_ColorQuantize(hDIB24bpp, FIQ_WUQUANT);

    RGBQUAD *Palette = FreeImage_GetPalette(hDIB8bpp);
    for (int i = 0; i < 256; i++)
    {
        Transparency[i] = 0xFF;
        if (Palette[i].rgbRed != 0x00 && Palette[i].rgbBlue != 0xFF && Palette[i].rgbGreen > 0x00)
        {
            Transparency[i] = 0x00;
        }
    }

    FreeImage_SetTransparencyTable(hDIB8bpp, Transparency, 256);

//  FreeImage_Save(FIF_PNG, hDIB8bpp, "out.png");
    FreeImage_Unload(hDIB24bpp);

    return hDIB8bpp;
}

原图:

结果:

原文地址:https://www.cnblogs.com/lewis-liu/p/9192996.html

时间: 2024-11-05 16:38:29

FreeImage 生成带透明通道的GIF的相关文章

将刀塔传奇中的jpg+mask文件转换为带透明通道的png文件

实际操作非常没有技术含量,不过想展示一下万能的python.虽然python的文字编码和空格对齐我很反感,但是不得不说,其接口设计非常优秀,让复杂的工作变得非常简单,这种思想也体现在第三方扩展上面. 刀塔传奇使用jpg+mask文件的形式,达到压缩资源的目的.jpg的压缩比非常优秀,而mask含有透明通道信息,这样就可以大大压缩图片大小. 不过我个人更倾向于png,使用png8+压缩纹理不会比这个方案更差,换来的是更加快的加载速度和内存的节约.尤其是在Unity中,我更希望Unity来管理纹理,

Photoshop做32位带Alpha通道的bmp图片

原文链接: http://blog.sina.com.cn/s/blog_65c0cae801016e5u.html 批量制作32位带Alpha通道的bmp图片,可以制作一个动作,内容可以如下: 1)合并图层 2) ctrl+单击图层选中图形 3)copy 4)在channel中新建alpha通道 5)paste 6) save as

微信公众号开发(三)生成带参数的二维码

微信公众号开发之生成带参数的二维码 做微信公众号开发的人员都知道用户海报作为公众号吸引用户是常见的渠道,那么我就说说这个海报的生成. 看了好多公众号发现他们的海报都是大同小异,一个漂亮的背景+自己的头像+专属二维码. 背景就不阐述了,用户的头像可以由公众号开发文档提供的方式获取(根据用户的openId),今天主要讲用户的专属二维码 所谓专属即便是一对一的. 二维码分为两种,临时二维码和永久二维码 /*生成永久二维码*/ public static String getPerpetualQR(St

Servlet动态验证码的生成-带数字和字母

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 一.实现的思路: (1)首先,需要创建一个Servlet.该Servlet通过字节型响应给客户端返回一个图片,该图片是通过JDK中Java 2D的类库来生成一个图片.图片的生成是依靠一个随机数来完成,然后将这个随机数写成图片格式.最后在Session将这个随机的字符串的状态保持住,以便在用户填写后进行对比. (2)其次,在需要加入验证码的JSP页面中,通过<img src="生成验证码

Force.com微信开发系列(八)生成带二维码的参数

为了满足用户渠道推广分析的需要,公众平台提供了生成带二维码的接口.使用该接口可以获得多个带不同场景值的二维码,用户扫描后,公众号可以接收到事件推送.目前有两种类型的二维码,分别是临时二维码和永久二维码,前者有过期时间,最大为1800秒,但能够生成较多数量,后者无过期时间,数量较少(目前参数只支持1到100000).两种二维码分别适用于账号绑定.用户来源统计等场景. 用户扫描带场景值二维码时,可能推送以下两种事件: 1. 如果用户还未关注公众号,则用户可以关注公众号,关注后微信会将带场景值关注事件

PHP在线生成带LOGO的二维码

PHP生成二维码的实例程序,网上有很多二维码生成程序,不过都是生成标准的二维码,最近的一个项目要求生成中间是小图标(LOGO)的二维码,后经不断查询资料,终于做出来了,主要核心是使用了国外的一个开源类库--QRCODE,生成确实方便,希望能为大家提供一份参考. 使用注意:在生成带lOGO的二维时:1.请将需要显示在二维码中的LOGO图像命名为emwlogo.gif,格式:gif,放在与ewmlogo.php文件同级的目录下2.请在文本框中输入正确的网址,若网址格式不对,则生成的二维码无效. 在线

任意两张带透明图像的一种形状过渡效果

一直想要一个Flash 那种形状渐变效果,这两天苦思冥想了一番实现了,先看效果. 一开始是往把贴图alpha通道识别成路径,建模想办法拉顶点的方向去,想来想去不是个好办法,后来还是决定直接基于位图实现,尽量采用gpu可以处理的方式. 然后往这边思考后,脑子里就浮现出了ditance field 这个概念,alpha表达的还是颜色,直接插值alpha会呈现出颜色渐变的结果. 而distance field 反映的是离边的远近,插值他就会呈现出每个像素离边的距离的变化. 确定方案后就是实现了. 我采

微信公众平台功能开发(生成带参数的二维码)

为了满足用户渠道推广分析的需要,公众平台提供了生成带参数二维码的接口.使用该接口可以获得多个带不同场景值的二维码,用户扫描后,公众号可以接收到事件推送. 目前有2种类型的二维码,分别是临时二维码和永久二维码,前者有过期时间,最大为1800秒,但能够生成较多数量,后者无过期时间,数量较少(目前参数只支持1--100000).两种二维码分别适用于帐号绑定.用户来源统计等场景. 用户扫描带场景值二维码时,可能推送以下两种事件: 如果用户还未关注公众号,则用户可以关注公众号,关注后微信会将带场景值关注事

SQL Server 2008 R2如何生成带数据的数据库脚本

1.对想要复制的数据库右键,"任务","生成脚本" 2.下面需要注意的是,默认情况下,只会生成仅架构的脚本,也就是说仅仅有表结构,而没有数据的空壳.所以需要额外的设置. 在设置脚本编写选项,选择"高级" 然后在"要编写脚本的数据类型",选择"架构和数据" 3.运行生成的脚本. 注意修改数据库文件的位置,因为可能脚本中的路径在目标计算机中并不存在. SQL Server 2008 R2如何生成带数据的数据库脚