画像のサイズ変更
概要
この記事では、GDI+ を利用して画像 (ファイル) のサイズ変更を行う方法を紹介します。言語は C++ を使います。
GDI+ の利用
GDI+ は従来の GDI と異なり、便利なクラスライブラリとして提供されています。C# などからも簡単に利用可能であるために、.NET Framework の一部と思われがちですが、実際には独立しており、ネイティブコードとして実行されます。C# での情報は比較的たくさんあるでしょうから、ここでは C++ を使ったコードサンプルを示します。
下記のコードは C:\foo.jpg を 207x156
のサイズに変換して C:\foo_s_80.jpg
という名前で保存します。フォーマットは JPEG で、画像品質は 80 としています。品質の最大値は 100 です。
#include <windows.h>
#include <stdio.h>
#include <gdiplus.h>
using namespace Gdiplus;
// 戻り値
// 成功時 -
GetImageEncoders が返す配列のインデックス
// 失敗時 - -1
int GetEncoderClsid(const
WCHAR* format, CLSID* pClsid) {
UINT num = 0;
UINT size = 0;
ImageCodecInfo* pImageCodecInfo = NULL;
GetImageEncodersSize(&num,
&size);
if(size == 0) {
return -1; // 失敗 -
GetImageEncodersSize 失敗
}
pImageCodecInfo =
(ImageCodecInfo*)(malloc(size));
if(pImageCodecInfo == NULL) {
return -1; // 失敗 - メモリ割り当て不可
}
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; // 成功
}
}
free(pImageCodecInfo);
return -1; // 失敗 - 要求した種類のエンコーダが存在しなかった
}
int main() {
// GDI+
の初期化
GdiplusStartupInput
gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken,
&gdiplusStartupInput, NULL);
//
原画像から Image オブジェクトを作成する
Image* pImgOrg =
Image::FromFile ( L"C:\\foo.jpg");
//
これから作成する画像用に Bitmap オブジェクトを作成
Bitmap* pBitmap = new
Bitmap ( 207, 156 );
//
Bitmap オブジェクトから Graphics オブジェクトを作成する
// ここで作成した Bitmap
オブジェクトに描画し、それを保存する。
Graphics* pGrfx =
Graphics::FromImage ( pBitmap );
//
ターゲットとなる矩形を Rect オブジェクトで表現しておく
// ここでは 207x156 (px) の矩形
Gdiplus::Rect rectDist ( 0,
0, 207, 156);
//
原画像の全体を rectDist で表した矩形領域へ写像する。
// "原画像の全体"
は第3引数~第6引数で表している。原画像の一部をクリップするなら
// ここでクリップしたい領域を指定する。
pGrfx->DrawImage (
pImgOrg,
rectDist,
0, 0, pImgOrg->GetWidth (), pImgOrg->GetHeight (),
UnitPixel);
//
// Bitmap の保存
//
//
エンコーダの CLSID 取得
// ここでは JPEG 画像を指定している. もし GIF
ならば GetEncoderClsid の
// 第一引数に L"image/gif" を渡す。
CLSID encoderClsid;
if ( -1 ==
GetEncoderClsid(L"image/jpeg", &encoderClsid) ) {
return FALSE;
}
// 品質指定
LONG lQuality = 80;
EncoderParameters
EncoderParams;
EncoderParams.Parameter[0].Guid =
EncoderQuality;
EncoderParams.Parameter[0].NumberOfValues = 1;
EncoderParams.Parameter[0].Type =
EncoderParameterValueTypeLong;
EncoderParams.Parameter[0].Value =
(VOID*) &lQuality;
EncoderParams.Count = 1;
//
Bitmap オブジェクトをファイルに保存。
pBitmap->Save (
L"C:\\foo_s_80.jpg" , &encoderClsid, &EncoderParams );
//
// クリーンアップ
//
delete pImgOrg;
delete pBitmap;
GdiplusShutdown(gdiplusToken);
return TRUE;
}
サンプルコードのダウンロード [VC++ 2003 プロジェクト, resize.zip]