WindowsCE プログラミングTIPS その8
   Independent JPEG GroupのJPEG Softwareを使おう    
 
JPEG圧縮保存方法と画面キャプチャトリック
第1版

[WindowsCEプログラミングTIPS インデックス]へ

■お断り

このTIPSの内容はIndependent JPEG Groupが配布するIndependent JPEG Groupの成果であるIndependent JPEG Group's JPEG SoftwareのWindowsCE上における使用方法を紹介するものです。

■はじめに

 IJG-JPEGLIBシリーズ最終回の今回はJPEG圧縮画像の保存方法を紹介します。ついでに画面キャプチャの方法も紹介します。

■おまけは画面キャプチャのトリック

  エラー処理等は完全ではありませんからあくまで参考まで。。。。
 実際にNEC MC-R520 65536/256両モードで動作確認してあります。

LRESULT CMainWin::OnFileSave(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &done)
{
	//****画面のキャプチャ****
	ShowWindow(m_hWnd,  SW_HIDE ); //このプログラム自体のWindowを隠します
	Sleep( 4000 );			//画面が落ち着くまで待ちます。4秒は十分な時間。
	long screen_width  = GetSystemMetrics(SM_CXSCREEN);//画面横サイズ
	long screen_height = GetSystemMetrics(SM_CYSCREEN);//画面縦サイズ
	//画面保存用のDIBバッファを作ります。
	BITMAPINFO			bmpinfo;
	LPBITMAPINFO		hbp = (LPBITMAPINFO)&bmpinfo;
	LPBITMAPINFOHEADER	bmi = &hbp->bmiHeader;
	bmi->biSize			= sizeof(BITMAPINFOHEADER);
	bmi->biWidth	 	= screen_width;
	bmi->biHeight	 	= screen_height;
	bmi->biPlanes		= 1;
	bmi->biBitCount      	= 24;
	bmi->biCompression	= BI_RGB;
	bmi->biXPelsPerMeter  = 0;
	bmi->biYPelsPerMeter  = 0;
	bmi->biClrUsed		= 0;
	bmi->biClrImportant   = 0;
	DWORD lineBytes = ((((bmi->biWidth * bmi->biBitCount) + 31) & ~31) >> 3);
	bmi->biSizeImage	 = (DWORD)( lineBytes * bmi->biHeight);
	HDC hdc = ::GetDC( m_hWnd );
	BYTE*	pBuffer;
	HANDLE hBMP = ::CreateDIBSection((HDC)hdc,hbp,DIB_RGB_COLORS, (void**)&pBuffer,NULL,0);
	//バッファに画面をコピーします。
	HDC hMemDC = CreateCompatibleDC(hdc);		
	SelectObject(hMemDC, hBMP);
		BitBlt( hMemDC, 0 , 0, screen_width, screen_height, hdc, 0, 0, SRCCOPY);
	DeleteDC(hMemDC);
	::ReleaseDC(m_hWnd, hdc );
	ShowWindow(m_hWnd, SW_SHOW); //再びこのプログラムのウィンドウを表示します。
	SetForegroundWindow(m_hWnd); //このプログラムウインドウをフォアグラウンドにします//****キャプチャ内容をJPEG圧縮してセーブ****
	HANDLE hFile = CreateFile( TEXT("\\test.jpg"), GENERIC_WRITE, FILE_SHARE_READ, NULL ,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
	struct  jpeg_error_mgr jerr;			//JPEGエラーハンドラー用構造体
	struct  jpeg_compress_struct cinfo;	//圧縮作業用構造体
	__try{
		cinfo.err = jpeg_std_error(&jerr);	//標準エラー処理
		jpeg_create_compress(&cinfo);	//圧縮の準備
		cinfo.image_width		= bmi->biWidth; //JPEG画像の横ドットサイズ
		cinfo.image_height	= bmi->biHeight;//JPEG画像の縦ドットサイズ
		cinfo.input_components	= 3; 		//1画素は3バイト
		cinfo.in_color_space	= JCS_RGB;	//入力画素はRGB形式
		jpeg_set_defaults(&cinfo);		//まずデフォルト設定値に
		jpeg_stdio_dest(&cinfo, hFile );	//出力ファイルハンドルを設定
		//次の行では画質を1〜100で指定します。
		//100が最高で圧縮率が低く、劣化が少なく記録できます。
		//圧縮率を高めるにはこの数値を小さくします。 
		jpeg_set_quality(&cinfo, 99, TRUE );
		//次の行では解凍時のDCTの演算方法を変更するものです。 
		//デフォルトではJDCT_ISLOWになっており画質優先になっています。 
		//この設定でもほとんど問題はないと思います。		
		cinfo.dct_method		= JDCT_IFAST;
		jpeg_start_compress(&cinfo,TRUE);	//圧縮開始
		long offset =  lineBytes*(bmi->biHeight-1);
		while (cinfo.next_scanline < cinfo.image_height) {
			JSAMPROW  praw 	= (JSAMPROW)( pBuffer + offset );
			offset -= lineBytes;
			jpeg_write_scanlines(&cinfo, (JSAMPARRAY)&praw, 1 );//1ライン入力
 		}
		jpeg_finish_compress(&cinfo);//圧縮を終了させます
		jpeg_destroy_compress(&cinfo);//圧縮に用いた作業領域などを解放します
	}
	__except(1){
		jpeg_destroy_compress(&cinfo);
		CloseHandle( hFile );
		DeleteObject( hBMP );
		CommandBar_Destroy(m_hwndCB);
		DestroyWindow(m_hWnd);
		return -1;
	}
	CloseHandle( hFile );
	DeleteObject( hBMP );
	CommandBar_Destroy(m_hwndCB);
	DestroyWindow(m_hWnd);
	return 0;
}

ソースファイルはこちら→tips8.lzh ただし何の保証もありません。(^^;
またIJG-JPEGLIBは入っていないので前回のTIPS記事を参考にビルドに挑戦してください。
 
■次回以降は。。。。

WinCEのWininetを用いたインターネットプログラミングの紹介を検討しています。。。。

===更新履歴===

2000/9/28 初稿

Reported by かっぴー

(C)2000 Windows CE FAN