소스 설명

 

0. 기능 설명

   jpeg이미지에 문자열을 추가하고 변경된 이미지를 출력한다.   

 

1. 실행 환경

   mfc 기반의 싱글모드에서 gdiplus를 연동 시킨다.

   리소스에 jpeg 이미지가 import되어있다.

   소스코드는 viwe 클래스의 OnDraw()에 구현

   반드시 platfromsdk february 2003 버전을 사용해야함.(다른 버전은 디버깅모드시 에러남)

 

2. 실행과정

   1. 리소스로 부터 jpeg이미지를 로딩하여 Stream 형태로 저장

   2. 저장된 stream을 메모리 디시에 넣고, 다시 메모리디시에 문자열을 추가한다.

   3. 2의 과정이 끝난 메모리 디시의 이미지를 Stream 형태, 파일 형태로 출력한다.

 

3. 왜한것임?

   gdi+의 자료가 생각보다 너무 적었다. gdi기반의 소스는 그 역사만큼 양도 많은데 gdi+

   작업할려고 하니 애로사항이 너무 많았다. 특히 단순히 이미지에 추가로 글자를 입히는

   작업도 예제 소스가 없어서 구현함.  

 

 

//추가 코드

void CGdiplustest2View::OnDraw(CDC* pDC)
{
 CGdiplustest2Doc* pDoc = GetDocument();
 ASSERT_VALID(pDoc);
 // TODO: add draw code for native data here

 

 //JPEG파일에 문자열을 추가하고 저장하는 루틴
 


 //리소트 텝에서 파일을 가져와서 버퍼에 저장
 HRSRC Resource = FindResource(NULL,MAKEINTRESOURCE(IDR_JPEG1),TEXT("jpeg"));
 
 if(!Resource)
  return;

 DWORD imageSize = SizeofResource(NULL, Resource);

 HGLOBAL hGlobal = LoadResource(NULL, Resource);

 LPVOID pData = LockResource(hGlobal);


 HGLOBAL hBuffer = GlobalAlloc(GMEM_MOVEABLE,imageSize);

 LPVOID pBuffer = GlobalLock(hBuffer);

 CopyMemory(pBuffer,pData,imageSize);

 GlobalUnlock(hBuffer);   //hbuffer이미지데이터들어가 있음.

 

 IStream *pStream;

 HRESULT hr=CreateStreamOnHGlobal(hBuffer,TRUE,&pStream);

 


 // 버퍼로부터 이미지 로드하기.

 Bitmap* pBitmap;
 pBitmap = (Bitmap*)Image::FromStream(pStream); //스트림으로 부터이미지를 로드한다.

 Bitmap MemBitmap(pBitmap->GetWidth(), pBitmap->GetHeight()); //가상의 영역에 로드한 이미지의 크기만큼의 비트맵 생성함

 Graphics memgraphics(&MemBitmap);    //메모리 dc 처럼 사용할 변수
 memgraphics.DrawImage(pBitmap,0,0);    //메모리 dc 에 로드한 이미지를 그린다.

 //글자추가.
 FontFamily fontFamily(L"tahoma");
 Font font(&fontFamily, 24,FontStyleRegular, UnitPixel);

 SolidBrush brush(Color(255,0,0,255));
 PointF pointF(100.0f,100.0f);
 memgraphics.DrawString(L"Overlap Test", -1, &font, pointF, &brush);


 //변경된 이미지 JPEG로 저장하기
 int nQuality = 100;
 EncoderParameters param;
 param.Count                       = 1;
 param.Parameter[0].Guid           = EncoderQuality;    //PlatformSDK를 February 2003 버전 사용해야 디버그모드에서 에러발생 안남
 param.Parameter[0].Type           = EncoderParameterValueTypeLong;
 param.Parameter[0].NumberOfValues = 1;
 param.Parameter[0].Value          = &nQuality;   

 CLSID jpegClsid;
 GetEncCLSID(L"image/jpeg", &jpegClsid);     

 

 //파일로 저장
 MemBitmap.Save(L"output.jpg", &jpegClsid, &param);

 
 
 //스트림으로 저장 후 화면 dc에 출력해줌.
 //스트림으로 저장하는 방법 설명한 사이트 : http://www.devpia.co.kr/Maeul/Contents/Detail.aspx?BoardID=51&MAEULNo=20&no=8375&ref=8375
 
 IStream *SaveStream = NULL;

 if(::CreateStreamOnHGlobal(NULL,TRUE,&SaveStream) == S_OK)
 {
  MemBitmap.Save(SaveStream,&jpegClsid,&param);
  
  Graphics G(pDC->m_hDC);
  Image I(SaveStream);
  SaveStream->Release();
  
  if(I.GetLastStatus()!=S_OK)
   return;
  
  G.DrawImage(&I,0,0);
 }

 delete pBitmap;
 pStream->Release();

}

 

BOOL CGdiplustest2View::GetEncCLSID(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

}

출처: http://blog.naver.com/space0215?Redirect=Log&logNo=30084302415

'MFC' 카테고리의 다른 글

스트링 형변환  (0) 2011.08.30
각종 윈도우 영역 크기 얻기  (0) 2011.08.26
마우스 press relese 이벤트 직접 설정하기  (0) 2011.08.26
윈도우 종료 하기  (0) 2011.08.26
시간 연산 방법  (0) 2011.08.26
Posted by pkss
,