テストを行いました。結果はLog.txtに出力されます。
コード:
#include "DxLib.h"
struct minmax_t {
int minx,miny,maxx,maxy;
};
minmax_t getSelectionMinMax(int graph) {
int prevDrawScreen=GetDrawScreen();
int gx,gy;
int softImage;
minmax_t res;
// 画像データを取得する
SetDrawScreen(graph);
GetGraphSize(graph,&gx,&gy);
softImage=MakeARGB8ColorSoftImage(gx,gy);
GetDrawScreenSoftImage(0,0,gx,gy,softImage);
// 不透明な部分の座標の最大値/最小値を取得する
res.minx=gx;
res.miny=gy;
res.maxx=-1;
res.maxy=-1;
#if 0
// APIを使ったアクセス(比較的安全そう)
for(int y=0;y<gy;y++) {
for(int x=0;x<gx;x++) {
int a,r,g,b;
GetPixelSoftImage_Unsafe_ARGB8(softImage,x,y,&r,&g,&b,&a);
if(a>0) {
if(x<res.minx)res.minx=x;
if(x>res.maxx)res.maxx=x;
if(y<res.miny)res.miny=y;
if(y>res.maxy)res.maxy=y;
}
}
}
#else
// メモリへの直接アクセス(比較的速そう)
unsigned char* imageData=(unsigned char*)GetImageAddressSoftImage(softImage);
int imagePitch=GetPitchSoftImage(softImage);
for(int y=0;y<gy;y++) {
for(int x=0;x<gx;x++) {
if(imageData[x*4+3]>0) {
if(x<res.minx)res.minx=x;
if(x>res.maxx)res.maxx=x;
if(y<res.miny)res.miny=y;
if(y>res.maxy)res.maxy=y;
}
}
imageData+=imagePitch;
}
#endif
// 画像データを開放する
DeleteSoftImage(softImage);
SetDrawScreen(prevDrawScreen);
return res;
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //初期化処理
// テスト用画像の生成
int graph=MakeScreen(4096,4096,TRUE);
SetDrawScreen(graph);
DrawCircle(1564,2043,1051,GetColor(255,255,255),TRUE);
SetDrawScreen(DX_SCREEN_FRONT);
ErrorLogAdd("-----------test information-----------\n");
const int iterationNum=10;
LONGLONG totalElapsedTime=0;
for(int i=0;i<iterationNum;i++) {
LONGLONG startTime,elapsedTime;
minmax_t minmax;
// 最大値・最小値を取得する
startTime=GetNowHiPerformanceCount();
minmax=getSelectionMinMax(graph);
elapsedTime=GetNowHiPerformanceCount()-startTime;
ErrorLogFmtAdd("try %3d : %.6fs (%d,%d)-(%d,%d)",i,(double)elapsedTime/1e6,
minmax.minx,minmax.miny,minmax.maxx,minmax.maxy);
totalElapsedTime+=elapsedTime;
}
ErrorLogFmtAdd("average elapsed time: %.8fs",(double)totalElapsedTime/iterationNum/1e6);
ErrorLogAdd("-----------test information end-----------\n");
DxLib_End();
return 0;
}
自分の環境で4096x4096の画像を入力したとき、API版が約0.76秒、メモリアクセス版が約0.60秒でした。
Windows Vista Home Premium SP2 32ビット
Intel(R) Core(TM)2Duo T8100 @2.10GHz 2.10GHz
RAM 4.00GB
DXライブラリ 3.11f
gcc 4.8.1 最適化: O2
厳密には、最初の1回の実行が他の実行より遅いという結果になりました。
API版
コード:
2817:try 0 : 1.102175s (513,992)-(2616,3094)
3576:try 1 : 0.736897s (513,992)-(2616,3094)
4315:try 2 : 0.735543s (513,992)-(2616,3094)
5036:try 3 : 0.716730s (513,992)-(2616,3094)
5753:try 4 : 0.713080s (513,992)-(2616,3094)
6485:try 5 : 0.728473s (513,992)-(2616,3094)
7216:try 6 : 0.726424s (513,992)-(2616,3094)
7931:try 7 : 0.710477s (513,992)-(2616,3094)
8663:try 8 : 0.728976s (513,992)-(2616,3094)
9395:try 9 : 0.727994s (513,992)-(2616,3094)
9400:average elapsed time: 0.76267689s
メモリアクセス版
コード:
2648:try 0 : 0.874176s (513,992)-(2616,3094)
3218:try 1 : 0.566053s (513,992)-(2616,3094)
3803:try 2 : 0.581408s (513,992)-(2616,3094)
4370:try 3 : 0.562619s (513,992)-(2616,3094)
4947:try 4 : 0.573127s (513,992)-(2616,3094)
5512:try 5 : 0.560519s (513,992)-(2616,3094)
6091:try 6 : 0.575705s (513,992)-(2616,3094)
6668:try 7 : 0.572978s (513,992)-(2616,3094)
7235:try 8 : 0.563046s (513,992)-(2616,3094)
7812:try 9 : 0.572819s (513,992)-(2616,3094)
7816:average elapsed time: 0.60024500s