zoukankan      html  css  js  c++  java
  • 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. 
    ";
            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;
    }

    原图:
    这里写图片描述这里写图片描述这里写图片描述
    结果:
    眉毛缺失这里写图片描述眉毛完整这里写图片描述

  • 相关阅读:
    梯度下降法实现python[转载]
    PAT Maximum Subsequence Sum[最大子序列和,简单dp]
    PAT Sign In and Sign Out[非常简单]
    PAT 1015 Reversible Primes[求d进制下的逆][简单]
    outlook 召回邮件 (zz)
    The Microsoft.Jet.OLEDB.4.0 provider is not registered on the local machine (zz)
    Determine Microsoft Database AccessEngine Version (zz)
    企业的十三中死法
    c#事件学习
    20071017我们的新家
  • 原文地址:https://www.cnblogs.com/brother-louie/p/13976548.html
Copyright © 2011-2022 走看看