JPEG 이미지 파일에 포함된 Metadata 를 읽어오기 위해 FreeImage 라이브러리를 사용하는 예
여기서는 앞서 작성했던 기능들을 모아서 클래스를 작성하고 프로젝트에서 쉽게 호출하는 예제를 소개한다
앞서 소개한 내용 참조
FreeImage의 다운로드 및 VC++ 프로젝트에 설정
FreeImage를 이용하여 JPEG 이미지의 특정 Metadata를 읽어오는 예제
Exiv2 커맨드라인 유틸리티를 이용하여 JPEG 메타데이타를 변경하는 예제
main.cpp
#include <iostream>
#include "FreeImageReader.h"
using namespace std;
/** 이 프로그램은 FreeImage 바이너리 배포판에 포함된 다음과 같은 3가지 파일을 필요로 합니다
1. FreeImage.h : 아래의 라이브러리 안에 구현된 함수들의 원형이 선언되어 있으므로 Compiler에 의해 참조됩니다
2. FreeImage.dll: 이 코드가 컴파일되어 생성되는 실행파일이 있는 곳에 복사해 두면 Linker에 의해 참조됩니다
3. FreeImage.lib: 프로젝트의 Library Drectories에 이 라이브러리가 있는 디렉토리를 등록하고
#pragma comment(lib, "FreeImage.lib") 디렉티브를 이용하면 Linker에 의해 참조됩니다
*/
int main(int argc, char *argv[]) {
FreeImageReader freeImageReader;
char* jpgFullPath = "D:\\test\\sample1.jpg";
cout << endl << "********* UserComment 태그 검색 테스트 **************" << endl;
char* tagName = "UserComment";
char* tagValue = freeImageReader.GetValue3(jpgFullPath, tagName);
cout << tagName << " : " << tagValue << endl;
cout << "*******************************************************" << endl;
return 0;
}
FreeImageReader.h
#pragma once
#include "FreeImage.h"
class FreeImageReader
{
public:
FreeImageReader(void);
~FreeImageReader(void);
FIBITMAP* LoadImage(const char* lpszPathName, int flag);
static void FreeImageErrorHandler(FREE_IMAGE_FORMAT fif, const char* message);
char* GetValue1(const char* tagName, FIBITMAP* dib, FREE_IMAGE_MDMODEL model);
char* GetValue2(const char* tagName, FIBITMAP* dib, FREE_IMAGE_MDMODEL model);
char* GetValue3(const char* jpgFullPath, const char* tagName);
};
FreeImageReader.cpp
#include <iostream>
#include "FreeImageReader.h"
#pragma comment(lib, "FreeImage.lib")
using namespace std;
FreeImageReader::FreeImageReader(void)
{
// call this ONLY when linking with FreeImage as a static library
FreeImage_Initialise();
// initialize your own FreeImage error handler
FreeImage_SetOutputMessage(FreeImageErrorHandler);
// print version & copyright infos
cout << "FreeImage " << FreeImage_GetVersion() << "\n";
cout << FreeImage_GetCopyrightMessage() << "\n\n";
}
FreeImageReader::~FreeImageReader(void)
{
// call this ONLY when linking with FreeImage as a static library
FreeImage_DeInitialise();
}
/** Generic image loader
@param lpszPathName Pointer to the full file name
@param flag Optional load flag constant
@return Returns the loaded dib if successful, returns NULL otherwise
*/
FIBITMAP* FreeImageReader::LoadImage(const char* lpszPathName, int flag)
{
FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
// check the file signature and deduce its format
// (the second argument is currently not used by FreeImage)
fif = FreeImage_GetFileType(lpszPathName, 0);
if(fif == FIF_UNKNOWN) {
// no signature ?
// try to guess the file format from the file extension
fif = FreeImage_GetFIFFromFilename(lpszPathName);
}
// check that the plugin has reading capabilities ...
if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) {
// ok, let's load the file
FIBITMAP *dib = FreeImage_Load(fif, lpszPathName, flag);
// unless a bad file format, we are done !
return dib;
}
return NULL;
}
/**
FreeImage error handler
@param fif Format / Plugin responsible for the error
@param message Error message
*/
void FreeImageReader::FreeImageErrorHandler(FREE_IMAGE_FORMAT fif, const char* message)
{
cout << "\n*** ";
if(fif != FIF_UNKNOWN) {
cout << FreeImage_GetFormatFromFIF(fif) << " Format\n";
}
cout << message;
cout << " ***\n";
}
/**
특정 태그에 대한 순차적 검색 예, 검색된 태그의 이름과 값을 출력함
*/
char* FreeImageReader::GetValue1(const char* tagName, FIBITMAP* dib, FREE_IMAGE_MDMODEL model)
{
FITAG *tag = NULL;
FIMETADATA *mdhandle = NULL;
mdhandle = FreeImage_FindFirstMetadata(model, dib, &tag);
char* _tagValue = NULL;
if(mdhandle) {
do {
char* _tagName = (char*) FreeImage_GetTagKey(tag);
if(strcmp(_tagName, tagName)==0)
{
FREE_IMAGE_MDTYPE tagType = FreeImage_GetTagType(tag);
// 7 = FIDT_UNDEFINED, An 8-bit byte that may contain anything, depending on the definition of the field.
_tagValue = (char*) FreeImage_TagToString(model, tag);
//cout << _tagName << " : " << _tagValue << " : " << tagType << endl;
break;
}else continue;
} while(FreeImage_FindNextMetadata(mdhandle, &tag));
}
// Unload the bitmap
FreeImage_Unload(dib);
return _tagValue;
}
/**
특정 태그에 대한 비순차적 검색의 예, 검색된 태그의 이름과 값을 출력함
*/
char* FreeImageReader::GetValue2(const char* tagName, FIBITMAP* dib, FREE_IMAGE_MDMODEL model)
{
FITAG *tagUserComment = NULL;
FreeImage_GetMetadata(model, dib, tagName, &tagUserComment);
char* _tagValue = NULL;
if(tagUserComment != NULL) {
char* _tagName = (char*) FreeImage_GetTagKey(tagUserComment);
FREE_IMAGE_MDTYPE tagType = FreeImage_GetTagType(tagUserComment);
// 7 = FIDT_UNDEFINED, An 8-bit byte that may contain anything, depending on the definition of the field.
_tagValue = (char*) FreeImage_TagToString(model, tagUserComment);
//cout << _tagName << " : " << _tagValue << " : " << tagType << endl;
}
// Unload the bitmap
FreeImage_Unload(dib);
return _tagValue;
}
/**
태그에 대한 비순차적 검색을 제공하며 사용 편의성을 위해 파라미터 수를 줄임
*/
char* FreeImageReader::GetValue3(const char* jpgFullPath, const char* tagName)
{
// Load the bitmap
FIBITMAP *dib = LoadImage(jpgFullPath, 0);
if(!dib) {
cout << "이미지 로드 실패" << endl;
return NULL;
}
FITAG *tagUserComment = NULL;
FreeImage_GetMetadata(FIMD_EXIF_EXIF, dib, tagName, &tagUserComment);
char* _tagValue = NULL;
if(tagUserComment != NULL) {
char* _tagName = (char*) FreeImage_GetTagKey(tagUserComment);
FREE_IMAGE_MDTYPE tagType = FreeImage_GetTagType(tagUserComment);
// 7 = FIDT_UNDEFINED, An 8-bit byte that may contain anything, depending on the definition of the field.
_tagValue = (char*) FreeImage_TagToString(FIMD_EXIF_EXIF, tagUserComment);
//cout << _tagName << " : " << _tagValue << " : " << tagType << endl;
}
// Unload the bitmap
FreeImage_Unload(dib);
return _tagValue;
}