GDI+ 활용
회사에서 워터마크 관련하여 작업하는 중에 GDI+를 찾게 되었고, 이걸 이용해서 문제를 해결하였다.
#include<Gdiplus.h>
using namespace Gdiplus;
우선 Gdiplus를 사용하기 위해서는 헤더파일을 먼저 선언 해주어야한다.
▶ Gdiplus png 이미지파일 생성하기
// GDI+ 을 사용하기위한 설정
GdiplusInit gdiplusinit;
ULONG_PTR gpToken;
GdiplusStartupInput gpsi;
if(GdiplusStartup(&gpToken, &gpsi, NULL) != Ok)
{
TRACE(_T("Do Not GDI+ initizlize!"));
return ;
}
//GDI+ 폰트 생성
REAL rSize = 30;
Gdiplus::Font gdiFont(_T("Arial"),rSize, FontStyleBold, Gdiplus::UnitPixel);
// 폰트이름, 글꼴크기 ,Unit이 지정한 단위 사용,
//GDI+ Graphics 생성
Graphics gFontWidth( GetDC(NULL) );
// 문자열 크기 저장
TCHAR szWaterMark[1024] = _T("administrator/192.168.*.*/Park-PC/SOFTWARE");
RectF rbound;
gFontWidth.MeasureString(szWaterMark, -1, &gdiFont, PointF(0,0), &rbound); // Measure 뜻은 측정하다, 법안
// png 생성을 위한 비트맵 생성
Bitmap bitmap( (int)rbound.Width, (int)rbound.Height, PixelFormat32bppARGB);
Graphics graphics_mark( &bitmap);
// 폰트의 각도설정
REAL rAngle = 0;
graphics_mark.RotateTransform(rAngle);
// 부드러움 모드 설정
graphics_mark.SetSmoothingMode(SmoothingModeAntiAlias);
// 텍스트의 브러쉬 설정
SolidBrush sBrush(Color(255,0,0,0));
// 텍스트 그리기
PointF ptText(0, 0);
graphics_mark.DrawString(szWaterMark, -1, &gdiFont, ptText, &sBrush);
CLSID pngClsid;
int result = GetEncoderClsid( L"image/png", &pngClsid );
if ( result == -1 )
{
TRACE("Encoder Error!!");
return ;
}
bitmap.Save( L"C:\\test\\test.png", &pngClsid, NULL );
GdiplusShutdown(gpToken);
GdiplusStartupInput(), GdiplusShutdown()
//함수원형
Status GdiplusStartup(
OUT ULONG_PTR *token,
const GdiplusStartupInput *input,
OUT GdiplusStartupOutput *output
);
void GdiplusShutdown(
ULONG_PTR token
);
2행 ~10행, 52행을 보면 GdiplusStartupInput(), GdiplusShutdown() 함수가 있다. 이 두 함수는 GDI+를 초기에 사용하고 해제하기 위해서 사용된다. 프로그램을 끝낼 때 반드시 GdiplusShutdown함수를 호출하여 GDI+라이브러리를 셧다운 하여야한다. GDI+는 실행중에 많은 리소스를 할당하는데 이 리소스를 반드시 해제해야한다.
GdiplusStartupInput() 함수의 인자 output은 초기화 결과를 돌려 주기 위한 구조체 인데, 필요없을 경우 NULL로 주어도 된다. Status형의 열거형으로 리턴하는데, 성공했을 경우 Ok가 리턴된다. Ok가 아닌 경우에는 GDI+를 사용할 수 없으므로 적절한 에러처리가 필요한다.
struct GdiplusInit {
GdiplusInit() {
GdiplusStartupInput inp;
GdiplusStartupOutput outp;
if ( Ok != GdiplusStartup( &token_, &inp, &outp ) )
{}
}
~GdiplusInit() {
GdiplusShutdown( token_ );
}
private:
ULONG_PTR token_;
};
2행 ~ 10행, 52행을 이런식으로 미리 코딩하여 사용할 수도 있다.
Gdiplus::Font
//함수원형
Font(
[in] const WCHAR *familyName,
[in] REAL emSize,
[in] INT style,
[in] Unit unit,
[in] const FontCollection *fontCollection
);
14행에서 생성한 폰트이다. 생성자 종류는 8개가 있는데, 그 중에서 사용한 생성 방식이다.
파라미터로는 순서대로 폰트이름, 폰트사이즈, 폰트스타일, Unit이 지정할 단위, 사용자 정의폰트
Gdiplus::MeasureString
//함수원형
Status MeasureString(
[in] const WCHAR *string,
[in] INT length,
[in] const Font *font,
[in, ref] const RectF &layoutRect,
[out] RectF *boundingBox
) const;
//The Graphics::MeasureString method measures the extent of the string in the specified font and layout rectangle
23행에서 사용된 함수이다. 이 함수는 문자열에 관한 정보를 측정하는 기능을한다. 지정된 글꼴을 직사각형에서의 문자열 범위를 측정한다.
문자열을 DC상에 그려낼때 크기가 필요하기에 사용된다.
GetEncoderClisid()
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
UINT num = 0; // number of image encoders
UINT size = 0; // size of the image encoder array in bytes
ImageCodecInfo* pImageCodecInfo = NULL;
GetImageEncodersSize(&num, &size);
if(size == 0)
return -1; // Failure
pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
if(pImageCodecInfo == NULL)
return -1; // Failure
GetImageEncoders(num, size, pImageCodecInfo);
for(UINT j = 0; j < num; ++j)
{
if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
{
*pClsid = pImageCodecInfo[j].Clsid;
free(pImageCodecInfo);
return j; // Success
}
}
free(pImageCodecInfo);
return -1; // Failure
}
44행 GetEncoderClisid함수는 API함수가 아닌 사용자가 정의한 함수를 호출한 것이다.
'훈, IT 공부 > C,C++,MFC' 카테고리의 다른 글
Visual Studio 2008 - fatal error C1859 미리 컴파일된 헤더에서 예기치 않은 오류가 발생했습니다. 컴파일러를 다시 실행하면 이 문제를 해결할 수 있습니다. (6) | 2019.06.17 |
---|---|
C/C++/Window, 서비스에서 UI 실행시키기 (6) | 2019.05.10 |
[MFC]CreateFont (0) | 2018.08.31 |
[MFC]트레이아이콘(Tray)과 풍선(Balloon) 알림 사용 (2) | 2018.08.12 |
[궁금점]winApi WriteFile 함수의 동작 (0) | 2018.06.02 |
댓글