Windows에서 제공하는 GDI+를 이용한 이미지 파일 변환을 생각난 김에 함 만들어 봤다.
개인적으로 OS에 들어 있는 것을 사용하는 걸 좋아하기 땜시.... ㅋㅋ
쓸모가 있을지는 모르겠으나.... 함 맹글어 본다.....
// zImageCvt.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.
//
#include "stdafx.h"
#include <windows.h>
#include <gdiplus.h>
#pragma comment (lib, "Gdiplus.lib")
// 시스템의 encoder 정보 load
INT nCntEncoder = 0;
Gdiplus::ImageCodecInfo* g_pImageCodecInfo = NULL;
int fnLoadEncoderInfo(void)
{
UINT num = 0; // number of image encoders
UINT size = 0; // size of the image encoder array in bytes
Gdiplus::GetImageEncodersSize(&num, &size);
if(size == 0)
return -1; // Failure
g_pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc(size));
if(g_pImageCodecInfo == NULL)
return -1; // Failure
GetImageEncoders(num, size, g_pImageCodecInfo);
nCntEncoder = num;
return num;
}
int fnPrintEncoderInfo(BOOL bOnlyDesc)
{
if( bOnlyDesc ){
for (int i=0; i<nCntEncoder; i++)
{
wprintf(_T("/%s\n"), g_pImageCodecInfo[i].FormatDescription);
}
}else{
for (int i=0; i<nCntEncoder; i++)
{
wprintf(_T("Format Desc. = %s, MimeType = %s, Ext = %s\n"),
g_pImageCodecInfo[i].FormatDescription,
g_pImageCodecInfo[i].MimeType,
g_pImageCodecInfo[i].FilenameExtension
);
}
}
return nCntEncoder;
}
int GetEncoderClsidByMimeType(const WCHAR* format, CLSID* pClsid)
{
for(UINT j = 0; j < (UINT)nCntEncoder; ++j)
{
if( wcscmp(g_pImageCodecInfo[j].MimeType, format) == 0 )
{
*pClsid = g_pImageCodecInfo[j].Clsid;
return j; // Success
}
}
return -1; // Failure
}
int GetEncoderClsidByFormatDesc(const WCHAR* format, CLSID* pClsid)
{
WCHAR *szFormat = (TCHAR *)::malloc( ::wcslen(format) + 1 );
if( szFormat == NULL ) return -1;
::ZeroMemory( szFormat, ::wcslen(format) + 1 );
::wcscpy( szFormat, format );
WCHAR *szReq = ::_wcsupr(szFormat);
for(INT j = 0; j < nCntEncoder; ++j)
{
if( wcscmp(g_pImageCodecInfo[j].FormatDescription, szReq) == 0 )
{
*pClsid = g_pImageCodecInfo[j].Clsid;
return j; // Success
}
}
return -1; // Failure
}
BOOL fnImageCvt(LPCTSTR lpszSRC, LPCTSTR lpszDst, const WCHAR* format)
{
BOOL bretval = FALSE;
do
{
// Create an Image object based on a PNG file.
Gdiplus::Image image(lpszSRC);
if( image.GetLastStatus() != Gdiplus::Ok )
break;
// Save the image.
CLSID jpgClsid;
if( GetEncoderClsidByFormatDesc(format/*L"image/jpeg"*/, &jpgClsid) < 0 )
break;
image.Save(lpszDst, &jpgClsid, NULL);
bretval = TRUE;
} while (FALSE);
return bretval;
}
void fnPrintSwitch(void)
{
::printf("이 명령에 대한 구문:\n\n");
::printf("zImageCvt\n");
::printf("zImageCvt\n");
::printf("[원본파일] [옵션] \n");
::printf("\t[원본파일] [결과파일] [옵션] \n");
::printf("옵션은 다음과 같음 \n");
::printf("옵션 \n");
::printf("/format : 입력한 format으로 변환합니다 \n");
::printf("----------------------------------------------------\n");
::printf("현재 변환가능 Descrions \n");
fnPrintEncoderInfo(TRUE);
}
int _tmain(int argc, _TCHAR* argv[])
{
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
do
{
// image encoder load
if( fnLoadEncoderInfo() < 0 ){
::printf("Image Encoder load에 실패했습니다.!");
break;
}
// 옵션맞는 함수 호출
TCHAR szSrc[MAX_PATH] = _T("");
TCHAR szDst[MAX_PATH] = _T("");
TCHAR szSwitch[MAX_PATH] = _T("");
TCHAR szTmp[MAX_PATH] = _T("");
switch( argc )
{
default: break;
case 2:
// 옵션 보기
if( wcscmp(argv[1], L"/h") == 0 ||
wcscmp(argv[1], L"-h") == 0 )
{
fnPrintSwitch();
}
break;
case 3:
::_tcscpy( szSrc, argv[1] );
::_tcscpy( szSwitch, argv[2]+1 );
break;
case 4:
::_tcscpy( szSrc, argv[1] );
::_tcscpy( szDst, argv[2] );
::_tcscpy( szSwitch, argv[3]+1 );
break;
}
if( ::_tcslen(szSrc) < 3 )
break;
//-------------------------------------------------------------------------------------
// 입력인자 보정
//-------------------------------------------------------------------------------------
if( ::_tcslen(szDst) < 3 )
{
::_tcsncpy( szDst, szSrc, ::_tcslen(szSrc) - 4 );
::_tcscat(szDst, _T("."));
::_tcscat(szDst, szSwitch);
}
// 실행
if( fnImageCvt( szSrc, szDst, szSwitch ) == FALSE )
printf("변환 실패!!");
} while (FALSE);
// 메모리 해제
if( g_pImageCodecInfo )
::free(g_pImageCodecInfo);
Gdiplus::GdiplusShutdown(gdiplusToken);
return 0;
}
소스코드 및 실행파일 :
'삽질' 카테고리의 다른 글
ImageSafer... Image Protection (1) | 2011.11.17 |
---|---|
std::remove_if .... (0) | 2011.11.06 |
ImageCodecInfo Class (0) | 2011.11.04 |
GetImageEncoders Function (0) | 2011.11.04 |
STL에서 동적할당 pointer 삭제 루틴. (0) | 2011.10.31 |