山本ワールド
Windowsプログラミング
アルゴリズム Vitual C++ 2008/2013によるWin32/Win64 APIレベルのプログラム 基礎 Vitual C++ 2008/2013によるAPIレベルのプログラム(32/64bit) Wix3でインストーラーを作る Visual C++ 2008 Standard Editonによるフォームアプリケーションのプログラム(32/64bit) Vitual C++ 2008 Standard EditonによるAPIレベルのプログラム(32/64bit) Windows 7対応 Visual C++ 2008 ExpressによるAPIレベルのプログラム Visual C++ 2005 ExpressによるAPIレベルのプログラム Visual C++ Versiosn 5 BORLAND C++ Windowsプログラム全般 Excel VBA その他コマンドプロンプト上でjpegファイルをトリムして保存するプログラム(GDI+)(32/64bit)
概要
コマンドプロンプト上で保存jpegファイル トリムするjpegファイル 選択する矩形の左上座標と幅と高さを指定して実行するトリムしたファイルが作成されます。
テスト環境
コンパイラ
Visual C++ 2008/2013 Express 32/64bit マルチバイト/UNICODE実行環境
Windows 10 Home(32bit/64bit)Windows 7 Enterprise Service Pack 1 64bit
動作例
以下にコマンドプロンプト上でimage1.jpgをトリミングしてimage2.jpgに保存する例を示す。
あらかじめ画像サイズがわかっていればバッチファイルを使用して例えば4分割等が簡単にできる。以下に4分割の例を示す。
複数のファイルを分割する場合は、バッチファイルからcall文を使用して4cut.batを呼び出す必要がある。
以下のバッチファイルは、引数で指定されたピクセル数をsetコマンドにより2分の1の値を求め、jpegcut1にその値を渡している。
複数のjpegファイルを4分割した場合は以下のようにバッチファイルを記述する。
jpegcut1 image2.jpg image1.jpg 100 50 150 100
image1.jpgの座標100,50を左上とし幅150、高さ100の矩形領域の外をトリミングしてimage2.jpgに保存している。あらかじめ画像サイズがわかっていればバッチファイルを使用して例えば4分割等が簡単にできる。以下に4分割の例を示す。
複数のファイルを分割する場合は、バッチファイルからcall文を使用して4cut.batを呼び出す必要がある。
以下のバッチファイルは、引数で指定されたピクセル数をsetコマンドにより2分の1の値を求め、jpegcut1にその値を渡している。
バッチファイルのソース 4cut.bat
set /a "A=%3 / 2"
set /a "H=%4 / 2"
jpegcut1 %1_1.jpg %2 0 0 %A% %H%
jpegcut1 %1_2.jpg %2 %A% 0 %A% %H%
jpegcut1 %1_3.jpg %2 0 %H% %A% %H%
jpegcut1 %1_4.jpg %2 %A% %H% %A% %H%
バッチファイルの呼び出し例
第1引数に保存ファイルの拡張子を除いた名称、第2引数にトリムするファイル、第3引数にトリムするファイルの横幅、第4引数に縦幅を指定する。以下に実行例を示す。4cut image3 image1.jpg 320 200
複数のjpegファイルを4分割した場合は以下のようにバッチファイルを記述する。
call 4cut image_cut1 image1.jpg 320 200
call 4cut image_cut2 image2.jpg 320 200
call 4cut image_cut3 image3.jpg 320 200
プログラムソースの概要
jpegcut1.cpp
_tmain
GdiplusStartupによりGDI+の初期化をします。
GetEncoderClsidによりjpegエンコーダを取得します。
コマンドラインの引数の個数をチェックし7個(自分自身のプログラム名を含む)の場合、
imgcut関数を呼び出しトリミングを実行します。
GdiplusShutdownにより終了処理を実行します。
imgcut
jpegファイルよりGdiplus::Imageオブジェクトを作成します。GDI+はunicodeしかサポートしないのでマルチバイトでコンパイルした場合は、unicodeに変換するコードを有効にします。
GetHorizontalResolution,
GetVerticalResolution関数によりソースファイルの解像度(DPI)を取得します。
new Bitmapにより保存用のBitmapオブジェクトを作成します。
SetResolutionでBitmapオブジェクトの解像度を設定します。
Bitmapオブジェクトを元にGraphicsオブジェクトを作成します。
DrawImage関数によりImageオブジェクトの指定領域をGraphicsオブジェクトに描画します。
DrawImage関数には沢山のオーバーロードされた形式があります。
描画が終了すればImageオブジェクトは不要なのでデストラクタでImageオブジェクトを解放します。
Save関数によりBitmapオブジェクトをファイルに保存します。マルチバイトでコンパイルした場合は、unicodeに変換するコードを有効にします。
Bitmapオブジェクト,Graphicsオブジェクトを解放します。
ソースコード
jpegcut1.cpp
// jpegトリミングソフト
// コマンドプロンプトで動作
// GDI+ランタイムが必要
// 使い方
// jpegcut1 保存ファイル 入力ファイル 切り取り位置x 切り取り位置y 切り取り横幅 切り取り高さ
#include <windows.h>
#include <gdiplus.h>
#include <stdio.h>
#include <tchar.h>
#include <locale.h>
#pragma comment(lib,"gdiplus.lib")
using namespace Gdiplus;
GdiplusStartupInput gdiSI;
ULONG_PTR gdiToken;
CLSID encoderClsid;
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid); // エンコーダーの取得
// srcで指定するjpegファイルの矩形領域(左上sx,sy 幅 width 高さ height)でトリミングしdtcで指定するjpegファイルに保存
int imgcut(TCHAR* dtc, TCHAR* src, int sx,int sy,int wdith, int height);
int _tmain(int argc, TCHAR** argv){
// UNICODE文字を標準出力に正しく表示させるためにロケールを設定
_tsetlocale(LC_ALL, _TEXT(""));
GdiplusStartup(&gdiToken, &gdiSI, NULL);
if(GetEncoderClsid(L"image/jpeg", &encoderClsid) < 0){
_tprintf(_TEXT("jpegエンコーダーが取得できませんでした。¥n"));
return (int)0;
}
if(argc == 7){
int sx = _ttoi(argv[3]);
int sy = _ttoi(argv[4]);
int width = _ttoi(argv[5]);
int height = _ttoi(argv[6]);
if(imgcut(argv[1], argv[2], sx, sy, width, height)){
_tprintf(_TEXT("jpegトリミングに失敗しました¥n"));
}
}else{
_tprintf(_TEXT("jpegトリミングソフト¥n¥n使い方¥n¥njpegcut1 保存ファイル 入力ファイル 切り取り位置x 切り取り位置y 切り取り横幅 切り取り高さ¥n"));
}
GdiplusShutdown(gdiToken);
return 0;
}
int imgcut(TCHAR* dtc, TCHAR* src, int sx, int sy,int width,int height){
Image* srcImage = 0;
#ifdef UNICODE
srcImage = Bitmap::FromFile(src);
#else
WCHAR srcFile[MAX_PATH];
MultiByteToWideChar(932, 0, src, -1, srcFile, sizeof(srcFile) / sizeof(WCHAR));
srcImage = Bitmap::FromFile(srcFile);
#endif
if(srcImage == 0 || srcImage->GetLastStatus() != Gdiplus::Ok){
srcImage->~Image();
return -1;
}
float px_res = srcImage->GetHorizontalResolution(); // jpgファイルの解像度DPI(横)
float py_res = srcImage->GetVerticalResolution(); // jpgファイルの解像度DPI(縦)
Bitmap* bmp = new Bitmap(width, height); // 保存用
bmp->SetResolution(px_res, py_res);
Graphics* MyGraphics = Graphics::FromImage(bmp);
MyGraphics->DrawImage(srcImage, 0,0,sx,sy,width,height,UnitPixel);
srcImage->~Image();
#ifdef UNICODE
bmp->Save(dtc, &encoderClsid);
#else
WCHAR dtcFile[MAX_PATH];
MultiByteToWideChar(932,0,dtc,-1,dtcFile,sizeof(dtcFile)/sizeof(WCHAR));
bmp->Save(dtcFile, &encoderClsid);
#endif
delete bmp;
delete MyGraphics;
return 0;
}
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid){
UINT num = 0;
UINT size = 0;
ImageCodecInfo* pImageCodecInfo;
GetImageEncodersSize(&num, &size);
if(size == 0)
return -1;
pImageCodecInfo = (ImageCodecInfo*)new char[size];
if(pImageCodecInfo == NULL)
return -1;
GetImageEncoders(num, size, pImageCodecInfo);
for(UINT n = 0; n<num; ++n) {
if(wcscmp(pImageCodecInfo[n].MimeType, format) == 0) {
*pClsid = pImageCodecInfo[n].Clsid;
delete pImageCodecInfo;
return n;
}
}
delete pImageCodecInfo;
return -1;
}
ソースコードと実行ファイルのダウンロード
ダウンロード jpegcut1.zip(51.7kB)
jpegcut1.cpp jpegcut1.exe 4cut.bat
Copyright (C) 2012 山本ワールド All Rights Reserved.