windows下FreeImage编译

FreeImage下载

​FreeImage下载地址​

windows下FreeImage编译_freeImage使用


点击左边的“Download”

windows下FreeImage编译_jpg_02


选择 “Download FreeImage 3.18.0 [WIN32/WIN64]”

windows下FreeImage编译_freeImage_03

vs2019打开工程

下载后解压,直接打开:FreeImage.2017.sln

windows下FreeImage编译_#include_04

生成dll、lib文件

windows下FreeImage编译_#include_05

接下来编译C++ Wraper的 测试工程

windows下FreeImage编译_jpg_06

接下来编译C++ Wraper的 测试工程

X:\FreeImageSource\Wrapper\FreeImagePlus\test\fipTest.2008.sln

将最外面的test.jpg拷贝到运行目录,挨个执行四个测试。

windows下FreeImage编译_jpg_07

可能遇到的问题

找不到头文件

在这里添加头文件的目录

windows下FreeImage编译_freeImage_08

找不到lib

在下面的位置添加

windows下FreeImage编译_freeImage_09

这不到dll

将对应的dll拷贝到程序运行目录

测试程序崩溃

将test.jpg拷贝到运行目录。

简单使用
创建一个工程,还有要用到一张图片。

(Please call me LeiFeng.)

首先来最简单的,加载一张JPEG图片。

#include “stdafx.h”
#include
#include “FreeImagePlus.h”

int _tmain(int argc, _TCHAR* argv[])
{
FreeImage_Initialise(TRUE);
FIBITMAP * JPEG = FreeImage_Load(FIF_JPEG, “test.jpg”, JPEG_DEFAULT);
//获取影像的宽高,都以像素为单位
int Width = FreeImage_GetWidth(JPEG);
int Height = FreeImage_GetHeight(JPEG);
std::cout << "Width: " << Width << "\nHeight: " <<Height << std::endl;
FreeImage_Unload(JPEG);
FreeImage_DeInitialise();
return 0;
}

windows下FreeImage编译_jpg_10

颜色调整

常见的图片颜色调整FreeImage都已经实现,调用对应的接口就可以了。这里调用一个反色,还有一个调整曲线。

windows下FreeImage编译_freeImage_11

(容我先擦一下鼻血)

代码

FreeImage_AdjustContrast(JPEG, 15.0);
FreeImage_AdjustBrightness(JPEG, 50.0);

//FreeImage_Invert(JPEG);
if (JPEG)
{
FreeImage_Save(FIF_BMP, JPEG, “test.bmp”, BMP_DEFAULT);
}

gif的拷贝

从一张gif生成一张一模一样的gif

BOOL bMemoryCache = TRUE;

fipMultiPage src(bMemoryCache);
fipMultiPage dst(bMemoryCache);

// You MUST declare this before using it.
// We will use the assignement operator, i.e. operator=()
fipImage image;

// Open src file (read-only, use memory cache)
src.open("example.gif", FALSE, TRUE);

if (src.isValid()) {
// Open dst file (creation, use memory cache)
dst.open("output.gif", TRUE, FALSE);

// Get src page count
int count = src.getPageCount();

// Clone src to dst
for (int page = 0; page < count; page++) {
// Load the bitmap at position 'page'
image = src.lockPage(page);
if (image.isValid()) {
// add a new bitmap to dst
dst.appendPage(image);
// Unload the bitmap (do not apply any change to src)
src.unlockPage(image, FALSE);
}
}
}
std::cout << FreeImage_GetPageCount(dst) << std::endl;
// Close src
src.close(0);
// Save and close dst
dst.close();

查看gif的metadate

fipMultiPage src(bMemoryCache);

src.open("example.gif", FALSE, TRUE);
fipImage image;
image = src.lockPage(0);
fipMetadataFind finder;
if (finder.findFirstMetadata(FIMD_ANIMATION, image, tagg)) {
do {
// process the tag
const void * p = tagg.getValue();
DWORD* pp = (DWORD *)p;
cout << "process the tag :" << tagg.getKey() << " " <<tagg.getType()<< " " << *pp << endl;
tagVector.push_back(tagg);
} while (finder.findNextMetadata(tagg));
}

最后用完记得unlockPage.

随便加载一个gif,得到对用的tag有下面这些

windows下FreeImage编译_freeImage使用_12

其中最重要的是FrameTime,表示帧占用的时间,单位是毫秒。其次是Loop,是一只循环播放(0)还是循环一次(1),

从静态图片生成gif

先下载几个png

windows下FreeImage编译_jpg_13

这个问题卡了我将近一天,文档上全是坑。

先上文档中专门说gif生成的代码

// assume we have an array of dibs which are already 8bpp and all the same size,
// and some float called fps for frames per second
FIMULTIBITMAP *multi = FreeImage_OpenMultiBitmap(FIF_GIF, “output.gif”, TRUE, FALSE);
DWORD dwFrameTime = (DWORD)((1000.0f / fps) + 0.5f);
for(int i = 0; i < 10; 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_CloseMultiBitmap(multi);

似乎先创建一个multiBitmap,然后各种appendPage就可以了。

Too Young.

先看一下gif的文件格式

GIF格式,是为使图片能够应用在在线(online)应用程序上所特别开发的图片格式。Gif,有时也被成为“Giff”,是一种无损,8位图片格式。“无损”是指100%的保持原始图片的像素数据信息。专业名词“8位”是指,所能表现的颜色深度——一个8位图像仅最多只能支持256种不同颜色(一个多余256种颜色的图片若用gif图片保存会出现失真)。

So,上面的那个png是32bit的,不是8位的图片是Append不上的,那就转格式呗。

自带一个convertTo8Bits的方法,但是转换出来是灰度的。

上论坛搜索答案,告知就是这样的。

要用一个colorQuantize方法,结果完全无效,上论然搜,告知要24位的图片才能转。

继续转呗,透明的部分全部变黑。

论坛上搜索无果,回头继续看png的格式

PNG图片类型
PNG格式有8位、24位、32位三种,下面是一些术语:

索引透明:类似于GIF,某一像素只有全透和全不透明两种效果
Alpha透明:半透明
PNG8 - 8位的PNG最多支持256(2的8次方)种颜色,8位的PNG支持索引透明和alpha透明。
PNG24 - 支持2的24次方种颜色,但不支持透明信息。
PNG32 - 32位的PNG在24位的PNG基础上增加了8位的透明信息,因此支持不同程度的半透效果。

默默地打开屁艾斯(PS),加载图片,存储为Web所用格式。

windows下FreeImage编译_freeImage使用_14

重新用代码记载,appendpage,全世界都安静了。

代码清单(用的plus的wraper)

#include “stdafx.h”
#include
#include “FreeImagePlus.h”
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{

BOOL bMemoryCache = TRUE;

fipMultiPage dst(bMemoryCache);


fipImage image1;
image1.load("11.png");
fipImage image2;
image2.load("2.png");
fipImage image3;
image3.load("3.png");

image2.convertTo24Bits();
image2.colorQuantize(FIQ_WUQUANT);
image3.convertTo24Bits();
image3.colorQuantize(FIQ_WUQUANT);

float fps = 3.0f;
DWORD dwFrameTime = (DWORD)((1000.0f / fps) + 0.5f);
fipTag tag;
tag.setKey("FrameTime");
tag.setType(FIDT_LONG);
tag.setCount(1);
tag.setLength(4);
tag.setValue(&dwFrameTime);
const void * p = tag.getValue();
DWORD* pp = (DWORD *)p;
cout << "Tag" << tag.getKey() << " " << *pp << endl;

//Set the loop of gif 0->loop forever 1->loop only once.
DWORD bloop = (DWORD)(1);
fipTag loopTag;
loopTag.setKey("Loop");
loopTag.setType(FIDT_LONG);
loopTag.setCount(1);
loopTag.setLength(4);
loopTag.setValue(&bloop);

image1.setMetadata(FIMD_ANIMATION, tag.getKey(), tag);
image2.setMetadata(FIMD_ANIMATION, tag.getKey(), tag);
image3.setMetadata(FIMD_ANIMATION, tag.getKey(), tag);

image1.setMetadata(FIMD_ANIMATION, loopTag.getKey(), loopTag);
image2.setMetadata(FIMD_ANIMATION, loopTag.getKey(), loopTag);
image3.setMetadata(FIMD_ANIMATION, loopTag.getKey(), loopTag);


dst.open("output.gif", TRUE, FALSE);

dst.appendPage(image1);
dst.appendPage(image2);
dst.appendPage(image3);

dst.close(); return 0;

}

最终效果,guang~

windows下FreeImage编译_jpg_15

第一张png是由ps导出的8位png,后面的两张用代码转的8位。