トップページ > 過去ログ > 記事閲覧
パレットカラー不具合?
名前:yoshihingis 日時: 2013/05/14 15:52

いつもお世話になっております。 Ver3.10cでパレットカラーの不具合らしき症状を見つけたので、ご報告いたします。 DirectX Ver:3.10c OS:Windows7 32bit Ultimate Visual Studio 2010使用 症状:画面サイズが縦長の時MakePAL8ColorSoftImage を使用した時、正常動作しない場合がある。  画像読み出しのメモリアドレスがずれていくような画になる。 コード説明; 16bit 1CHグレースケール Raw画像データを読み込み表示させるプログラムです。動作確認用なので、同じ画像が表示され続け、静止画を出しているのと同じ状態です。  720x405,530X707,600x600,760x980の4種類の画像サイズを読み込み表示させてみました。  inheight,inwidthで描画ウィンドウの高さと幅を設定しています。描画ウィンドウと画像サイズは一致しさせています。  元から16bit 1CHのグレースケール画像なのでR,G,B,アルファブレンドの8bitx4CH分のデータを書き込む手間を省くため、MakePAL8ColorSoftImageでパレットを作り、見かけ上8bit1CH分のデータをimage0に書き込むようにしていたのですが、530x707の縦長画像のときに正常に画が出ません。(いくつか他のサイズの縦長画像でも試しましたが症状は再現しました。)  ただ、画像サイズが大きくなると、正常になります。760x1090の画像では正常に画が出ます。  横長の画像や、縦横が同じサイズの画像では、特に今のところ異常は出ていません。  コメントアウトしていますが、パレットカラーではなく、MakeARGB9ColorSoftImageを使用すると、縦長画像530x707の画像でもおかしな画は出なくなります。  コード上、何か問題があればご指摘ください。  パレットカラー使用で、縦長画像(それもある画サイズ以下)で起こるので、DXライブラリの不具合ではないかと思っているのですが。  ご助言を頂ければ幸いです。  以上、よろしくお願いいたします。 #include "DxLib.h" #include <stdio.h> #include <string.h> #include <stdlib.h> #include <omp.h> int WindowWidth = 1920; int WindowHeight = 1200; //int inwidth = 720; //int inheight = 405; int inwidth = 530; int inheight = 707; //int inwidth = 600; //int inheight = 600; //int inwidth = 760; //int inheight = 1090; //垂直同期Wait数 int VsyncCount = 3; int Color0,Color1,Color2; int i; //Key入力検出用 int Key[256]; char tmpKey[256]; int KeyWait = 0; long long int StartTime0,EndTime0,EndTime1,EndTime2,EndTime3,EndTime4,EndTime5; BYTE *image0; //FILE NAME用 char ch1[512],ch2[512] ; //画像メモリエリア unsigned short* pSrc16u_all; unsigned short* pSrc16u_1; unsigned char* pSrc8u_1; FILE *fp1; int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { int handle0, grhandle0 ; //入力画像エリア確保 pSrc16u_all = (unsigned short*)malloc(sizeof(unsigned short)*inwidth*inheight); //入力画像を8bitシフト後のエリア確保 pSrc16u_1= (unsigned short*)malloc(sizeof(unsigned short)*inwidth*inheight); //出力8bitデータ画像 pSrc8u_1= (unsigned char*)malloc(sizeof(unsigned short)*inwidth*inheight); //LCD表示初期設定 // DXライブラリの初期化 if( DxLib_Init() < 0 ) return -1; //描画Windowsのサイズ設定 SetGraphMode( WindowWidth , WindowHeight , 32 ) ; ChangeWindowMode(FALSE); // ウィンドウモードに設定 SetDrawScreen( DX_SCREEN_BACK ); //描画先を表画面に設定 // 空のフルカラー画像を作成する //ALFA Blend Handle //handle0 = MakeARGB8ColorSoftImage(inwidth,inheight) ; //Palette Color Handle handle0 = MakePAL8ColorSoftImage(inwidth,inheight) ; //パレットカラーNormal for(i = 0;i < 256;i++){ SetPaletteSoftImage(handle0,i,i,i,i,0); } //作成した画像handleの先頭アドレスを検出する。 image0 = ( BYTE * )GetImageAddressSoftImage( handle0 ) ; //画像データの読み込み //image1 W530xH707 strcpy(ch1,"Test530x707.raw"); //image2 W720x405 //strcpy(ch1,"Test720x405.raw"); //image3 600x600 //strcpy(ch1,"Test600x600.raw"); //image4 760x1090 //strcpy(ch1,"Test760x1090.raw"); fp1 = fopen(ch1,"rb"); if(fp1 == NULL){ printf("Input FILE Error!!\n"); getchar(); return -1; } fread(pSrc16u_all,sizeof(unsigned short),inwidth*inheight,fp1); fclose(fp1); //DEBUG 全てのデータから1枚Saveする。 fp1 = fopen("testout_img.raw","wb"); if(fp1 == NULL){ printf("Output FILE Error!!\n"); getchar(); return -1; } fwrite(pSrc16u_all,sizeof(unsigned short),inwidth*inheight,fp1); fclose(fp1); // 赤色の値を取得 Color0 = GetColor( 255 , 0 , 0 ) ; // 青色の値を取得 Color1 = GetColor( 0 , 0 , 255 ) ; // 緑色の値を取得 Color2 = GetColor( 0 , 255 , 0 ) ; //LCDのVsyncを待ってLOOPをSTARTさせる。 WaitVSync(1) ; //動画像表示(無限LOOPにしている:抜け出しはキー割り込み) while(ProcessMessage()==0){ //処理時間の測定START StartTime0 = GetNowCount() ; //全ての画像から、1Frameデータを読み出す。 for(i=0;i<inwidth*inheight;i++){ pSrc16u_1[i] = pSrc16u_all[i]>>8; pSrc8u_1[i] = (unsigned char)pSrc16u_1[i]; } //画像データのコピー //Palaette Color Handle時使用 memcpy(image0,pSrc8u_1,sizeof(char)*inwidth*inheight); //ARGB Color Handle時使用 //for(i=0;i<inheight*inwidth;i++){ // image0[i*4 ] = pSrc8u_1[i]; // image0[i*4+1] = pSrc8u_1[i]; // image0[i*4+2] = pSrc8u_1[i]; // image0[i*4+3] = 255; //Alfa Data //} //グラフィックハンドルを作成 grhandle0 = CreateGraphFromSoftImage( handle0 ) ; EndTime0 = GetNowCount() ; ClearDrawScreen();//ScreenのClear //描画命令 DrawGraph( 0, 0, grhandle0, FALSE ) ; //Image Information DrawFormatString( 0,20 , Color0, "Through Test" ) ; DrawFormatString( 0,40 , Color0, "ProcessTime0:%d[msec]\n",EndTime0-StartTime0 ) ; DrawFormatString( 0,60 , Color0, "VsyncCount:%d\n",VsyncCount ) ; WaitVSync(VsyncCount) ; ScreenFlip(); //裏画面を表画面に反映 //メモリ読み込んだ画像を消去する。 //これを入れないと、多数の静止画を読み込んだ時、メモリが更新されなくなる。 InitGraph() ; //処理時間の測定END //KeyWait時間調整 if(VsyncCount<=1) { KeyWait = 4; } else if(VsyncCount==2) { KeyWait = 3; } else { KeyWait = 2; } //key Sense GetHitKeyStateAll( tmpKey ); // 全てのキーの入力状態を得る for( int i=0; i<256; i++ ){ if( tmpKey[i] != 0 ){ // i番のキーコードに対応するキーが押されていたら Key[i]++; // 加算 } else { // 押されていなければ Key[i] = 0; // 0にする } } //Vsync Wait Time Cahnge if( Key[KEY_INPUT_NUMPAD3] >= KeyWait){ VsyncCount = VsyncCount + 1; if(VsyncCount >= 10) VsyncCount = 10; } if( Key[KEY_INPUT_NUMPAD1] >= KeyWait){ VsyncCount = VsyncCount - 1; if(VsyncCount <= 1) VsyncCount = 1; } //Program終了 if( Key[ KEY_INPUT_END ] >= 1 ){ // Endキーが押されていたら DeleteSoftImage( handle0 ) ; DxLib_End(); //終了 return 0; } }//__while // 使い終わっったメモリ解放 free(pSrc16u_all); free( pSrc16u_1); free(pSrc8u_1); // 使い終わったら解放 DeleteSoftImage( handle0 ) ; // キー入力待ち WaitKey(); // DXライブラリの後始末 DxLib_End(); // ソフトの終了 return 0; }

Page: 1 |

Re: パレットカラー不具合? ( No.1 )
名前:yoshihingis 日時:2013/05/15 09:26

縦長画像ではパレットカラーが正常動作しないようだとご報告させて頂きましたが、横幅が600pixel未満、つまり599pixel以下だと、縦長、横長、正方形に関わらずパレットカラーは正常動作しないようです。  横幅が600pixel以上であれば、縦長画像でもパレットカラーは正常動作するようです。  今は1920x1200に全体のウィンドウサイズ設定にしていますが、この設定を変えたときでも、横幅599pixel以下でカラーパレットが正常動作しなくなるのか、パレットカラーの異常は別の横幅サイズ以下で生じるようになるのか、まではまだ追い切れていません。  以上、追加検討事項の報告まで。
Re: パレットカラー不具合? ( No.2 )
名前:管理人 日時:2013/05/19 11:26

yoshihingisさんが載せてくださったプログラムで正常に表示できない条件は 「画像の横幅ドット数が4の倍数ではない場合」 となります MakeXXXXColorSoftImage で作成される画像データは、1ライン辺りのバイト数を 4の倍数に合わせています なので、1ドット辺り32ビット( 4バイト )のフォーマットでは横幅が何ドットでも バイト数は必ず4の倍数になるのでこの仕様は気にする必要はありませんが、 1ドット辺り8ビット( 1バイト )のパレットカラー画像の場合はこの仕様の影響を受けます 横幅 → 1ライン辺りのバイト数 1dot → 4byte 2dot → 4byte 3dot → 4byte 4dot → 4byte 5dot → 8byte 6dot → 8byte 7dot → 8byte 8dot → 8byte 9dot → 12byte 10dot → 12byte 11dot → 12byte . . . C言語では以下の式で計算できます パレット画像の1ライン辺りのバイト数 = ( 横幅 + 3 ) / 4 * 4; この式の計算と同じ結果を取得するための関数が無かったので追加しました よろしければこちらをダウンロードしてください m(_ _)m http://homepage2.nifty.com/natupaji/DxLib/DxLibVCTest.exe // VisualC++ 用 http://homepage2.nifty.com/natupaji/DxLib/DxLibBCCTest.exe // BorlandC++ 用 http://homepage2.nifty.com/natupaji/DxLib/DxLibGCC_DevCppTest.exe // Dev-C++ 用 http://homepage2.nifty.com/natupaji/DxLib/DxLibGCC_MinGWTest.exe // MinGW 用 http://homepage2.nifty.com/natupaji/DxLib/DxLibDotNet.zip // .NET用 http://homepage2.nifty.com/natupaji/DxLib/DxLibMakeTest.exe // ソース (中身を既存のライブラリのファイルに上書きして、BCCをお使いの 場合は『再構築』を、VCをお使いの場合は『リビルド』を、 Dev-C++をお使いの方は「Rebuild All(Ctrl+F11)」をして下さい) // ソフトウエアイメージハンドルのメモリに格納されている画像データの1ライン辺りのバイト数を取得する int GetPitchSoftImage( int SIHandle ) ; 上記関数を使用してパレット画像の全ドットにアクセスする処理は以下のような書き方になります unsigned char *pal8; int pitch; int i; int j; pal8 = ( unsigned char * )GetImageAddressSoftImage( handle ); pitch = GetPitchSoftImage( handle ); for( i = 0; i < height; i++, pal8 += pitch ) { for( j = 0; j < width; j++ ) { pal8[ j ] = 100; } } ご不明な点がありましたらお訊ねください
Re: パレットカラー不具合? ( No.3 )
名前:yoshihingis 日時:2013/05/20 14:47

管理人様ありがとうございました。 パレットカラー時は横幅は、4の倍数でなくていけないという制約を知らなかった為、お手数をおかけいたしました。 画像データの引き渡し部分を以下のように変更することにより、横幅が4の倍数でなくても、うまく表示することが出来ました。  またpitch関数の実装どうもありがとうございました。 pitch = GetPitchSoftImage( handle0 ); for( i = 0; i < inheight; i++ ) { for( j = 0; j < inwidth; j++ ) { image0[i*pitch + j ] = pSrc8u_1[i*inwidth + j]; } }

Page: 1 |