비트맵 데이터를 GIF를 저장해보자. 먼저 repo에서 header only https://github.com/charlietangora/gif-h 소스를 다운로드 받자. 기본 예제는 아래와 같다.
#include <vector>
#include <cstdint>
#include <gif.h>
int main()
{
int width = 100;
int height = 200;
std::vector<uint8_t> black(width * height * 4, 0);
std::vector<uint8_t> white(width * height * 4, 255);
auto fileName = "bwgif.gif";
int delay = 100;
GifWriter g;
GifBegin(&g, fileName, width, height, delay);
GifWriteFrame(&g, black.data(), width, height, delay);
GifWriteFrame(&g, white.data(), width, height, delay);
GifEnd(&g);
return 0;
}
위 코드를 실행하면 100 x 200 검정, 흰색 이미지가 생성된다. 아래 코드에서 GifWriteFrame 메서드가 여러 장에 파일을 만드는 것으로 확인된다.
GifWriteFrame(&g, black.data(), width, height, delay);
GifWriteFrame(&g, white.data(), width, height, delay);
GITHUB README.md 를 확인하면 RGBA8 형식만 지원된다고 명시되어있다.
Only RGBA8 is currently supported as an input format. (The alpha is ignored.)
RGB 오더링이나 DEPTH 가 다른 비트맵은 지원되지 않는다.
GDIPLUS로 이미지를 로딩하고 GIF로 저장해보자.
#include <iostream>
using namespace std;
#include <windows.h>
// Gdiplus
#pragma comment( lib, "gdiplus.lib" )
#include <gdiplus.h>
static const wchar_t* filename = L"G:\\bab.png";
#include <vector>
#include <cstdint>
#include "gif.h"
int main()
{
// Start Gdiplus
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
// GDIPLUS 인스턴스를 초기화 한다.
// Load the image filename 패스로 이미지를 로딩한다.
Gdiplus::Bitmap* bitmap = Gdiplus::Bitmap::FromFile(filename);
// 로딩된 이미지의 format 정보를 확인한다. gif-h 라이브러리에서는 RGBA8 만 지원한다고 한다.
Gdiplus::PixelFormat format;
format = bitmap->GetPixelFormat();
switch (format) {
case PixelFormat1bppIndexed: cout << "PixelFormat1bppIndexed" << endl; break;
case PixelFormat4bppIndexed: cout << "PixelFormat4bppIndexed" << endl; break;
case PixelFormat8bppIndexed: cout << "PixelFormat8bppIndexed" << endl; break;
case PixelFormat16bppGrayScale: cout << "PixelFormat16bppGrayScale" << endl; break;
case PixelFormat16bppRGB555: cout << "PixelFormat16bppRGB555" << endl; break;
case PixelFormat16bppRGB565: cout << "PixelFormat16bppRGB565" << endl; break;
case PixelFormat16bppARGB1555: cout << "PixelFormat16bppARGB1555" << endl; break;
case PixelFormat24bppRGB: cout << "PixelFormat24bppRGB" << endl; break;
case PixelFormat32bppRGB: cout << "PixelFormat32bppRGB" << endl; break;
case PixelFormat32bppARGB: cout << "PixelFormat32bppARGB" << endl; break;
case PixelFormat32bppPARGB: cout << "PixelFormat32bppPARGB" << endl; break;
case PixelFormat48bppRGB: cout << "PixelFormat48bppRGB" << endl; break;
case PixelFormat64bppARGB: cout << "PixelFormat64bppARGB" << endl; break;
case PixelFormat64bppPARGB: cout << "PixelFormat64bppPARGB" << endl; break;
case PixelFormat32bppCMYK: cout << "PixelFormat32bppCMYK" << endl; break;
case PixelFormatMax: cout << "PixelFormatMax" << endl; break;
break;
}
const auto bpp = Gdiplus::GetPixelFormatSize(format);
const auto w = bitmap->GetWidth();
const auto h = bitmap->GetHeight();
const auto size = w * h * bpp / 8;
Gdiplus::BitmapData data;
const Gdiplus::Rect rect(0, 0, w, h);
bitmap->LockBits(&rect, Gdiplus::ImageLockModeRead, format, &data);
// delete the image when done
auto fileName = "bwgif.gif";
GifWriter g;
GifBegin(&g, fileName, w, h, 20);
GifWriteFrame(&g, reinterpret_cast<BYTE*>(data.Scan0), w, h, 50);
GifEnd(&g);
bitmap->UnlockBits(&data);
delete bitmap;
bitmap = nullptr;
// Shutdown Gdiplus
Gdiplus::GdiplusShutdown(gdiplusToken);
return 0;
}
쉽게 사용할 수 있으나 DEPTH 가 다른 경우에 대한 처리가 미비하다.
tiff alpha 태그 정보 기입 (0) | 2021.04.29 |
---|---|
비주얼 스튜디오에서 STB 라이브러리 사용하기 (0) | 2021.01.23 |
LIBTIFF Stable(안정) 버전 확인 하기 (1) | 2021.01.14 |
LCMS2-2.12 릴리즈 정보 (0) | 2021.01.14 |
ISF(Ink Serialized Format) (1) | 2021.01.07 |
댓글 영역