マトリクスサイズ | bluenoiseex()が発生する値の範囲 | ファイルサイズ | bluenoise()が発生する値の範囲 |
---|---|---|---|
256×256 | 0~0x0000ffff(0~ 65,535) | 埋め込みデータなのでファイルなし | 0~0x00007fff(0~32767) |
512×512 | 0~0x0003ffff(0~ 262,143) | 1メガバイト | 0~0x00007fff(0~32767) |
1024×1024 | 0~0x000fffff(0~ 1,048,575) 百万。乱数系列の代用には十分 | 4メガバイト | 0~0x00007fff(0~32767) |
2048×2048 | 0~0x003fffff(0~ 4,194,303) | 16メガバイト | 0~0x00007fff(0~32767) |
4096×4096 | 0~0x00ffffff(0~ 16,777,215) 24bitカラー画像の色数 | 64メガバイト | 0~0x00007fff(0~32767) |
8192×8192 | 0~0x03ffffff(0~ 67,108,863) 印刷幅8メートルの特殊なプリンタ(国宝のアーカイブ作成用)で唯一の利用実績 | 256メガバイト | 0~0x00007fff(0~32767) |
16384×16384 | 0~0x0fffffff(0~268,435,455) この精度を使っている例はゼロ(CYMK用の8192×8192マトリクス4枚に分割などが考えられる) | 1024メガバイト(1ギガバイト) | 0~0x00007fff(0~32767) |
/////////////////////////////// // ブルーノイズ系列のシード設定 // int seed; seed値 // 返り値 // 負....エラー(INITIALIZE_ERROR...初期化エラー(クラスのインスタンス生成に失敗:メモリ不足)) typedef int (__stdcall* SBLUENOISE)(int seed); extern SBLUENOISE sbluenoise; ///////////////////////// // ブルーノイズ系列の取得(0~RAND_MAX) // RAND_MAXは0x7fff(32767)なので粗い // 返り値 // 負....エラー(INITIALIZE_ERROR...初期化エラー(クラスのインスタンス生成に失敗:メモリ不足)) // ブルーノイズ系列 typedef int (__stdcall* BLUENOISE)(); extern BLUENOISE bluenoise; ///////////////////////// // 精細なブルーノイズ系列の取得(0~size*size) // ファイルを使わないサイズ(256*256)でも0~65535と細かい // 256* 256 0~0x0000ffff(0~ 65,536-1) ファイルを使わない // 512* 512 0~0x0003ffff(0~ 262,144-1) 1Mバイト // 1024* 1024 0~0x000fffff(0~ 1,048,576-1) 4Mバイト // 2048* 2048 0~0x003fffff(0~ 4,194,304-1) 16Mバイト // 4096* 4096 0~0x00ffffff(0~ 16,777,216-1) 64Mバイト // 8192* 8192 0~0x03ffffff(0~ 67,108,864-1) 256Mバイト // 16384*16384 0~0x0fffffff(0~268,435,456-1) 1024Mバイト(1Gバイト) // 返り値 // 負....エラー(INITIALIZE_ERROR...初期化エラー(クラスのインスタンス生成に失敗:メモリ不足)) // ブルーノイズ系列 typedef int (__stdcall* BLUENOISEEX)(); extern BLUENOISEEX bluenoiseex; ///////////////////////// // ブルーノイズ マトリクス保存・読込フォルダの設定、マトリクスサイズの設定 // 通常(0~RAND_MAX)の範囲のブルーノイズの生成では設定しない // bluenoiseex()で精細なブルーノイズを取得する目的がある場合に設定する // 入力 // const char* pfolder; マトリクスファイルの存在する/を生成するフォルダ名 // NULLあるいは""を指す場合は256×256サイズの組み込みマトリクスを利用する // int size; マトリクスサイズ(512/1024/2048/4096/8192/16384) // 1024の場合、1024×1024のブルーノイズマトリクスを生成する。ファイルサイズは4メガバイト // 返り値 // 負....エラー(INITIALIZE_ERROR...初期化エラー(クラスのインスタンス生成に失敗:メモリ不足)) // 負....エラー(FILE_OPEN_ERROR....保存できない、読み込みできない) // (MEMORY_SHORTAGE....メモリ不足) // 指定したフォルダのsizexsizeraw.datというファイルを読み込む // sizeが1024の場合は1024x1024raw.datというファイル名になる // ファイルが無い場合はファイルを作成する // sizeが大きくなるほど高品質のbluenoiseを生成する typedef int (__stdcall* SETBLUENOISEMATRIX)(const char* pfolder,int size); extern SETBLUENOISEMATRIX setbluenoisematrix;DLLのロードと解放は以下の通り
#include "bluenoisecallback.h" HINSTANCE bn_dllinstance; // dllインスタンス // DLL エントリーポイント SBLUENOISE sbluenoise; BLUENOISE bluenoise; BLUENOISEEX bluenoiseex; SETBLUENOISEMATRIX setbluenoisematrix; ORDEREDDITHER2 ordereddither2; ORDEREDDITHER4 ordereddither4; ORDEREDDITHERLINE2 orderedditherline2; ORDEREDDITHERLINE4 orderedditherline4; { // .... // ロード // gmodulepathには、実行ファイルのパスが入っている。 // 実行ファイルのパスに"bluenoisedll.dll"が入っているとする char filename[FILENAME_MAX]; sprintf(filename,"%sbluenoisedll.dll",gmodulepath); bn_dllinstance = LoadLibrary(filename); if(bn_dllinstance == NULL) { char buffer[512]; sprintf(buffer,"DLLファイル bluenoisedll.dll のロードに失敗しました"); AfxMessageBox(buffer,MB_OK | MB_ICONEXCLAMATION); return(2); } sbluenoise = (SBLUENOISE)GetProcAddress(bn_dllinstance,"sbluenoise"); bluenoise = (BLUENOISE)GetProcAddress(bn_dllinstance,"bluenoise"); bluenoiseex = (BLUENOISEEX)GetProcAddress(bn_dllinstance,"bluenoiseex"); setbluenoisematrix = (SETBLUENOISEMATRIX)GetProcAddress(bn_dllinstance,"setbluenoisematrix"); if(sbluenoise == NULL || bluenoise == NULL || bluenoiseex == NULL || setbluenoisematrix == NULL) { char buffer[512]; sprintf(buffer,"DLLファイル bluenoisedll.dll(or bluenoiseutf8dll) のバージョンが異なります"); AfxMessageBox(buffer,MB_OK | MB_ICONEXCLAMATION); FreeLibrary(bn_dllinstance); return(2); } ordereddither2 = (ORDEREDDITHER2)GetProcAddress(bn_dllinstance,"ordereddither2"); ordereddither4 = (ORDEREDDITHER2)GetProcAddress(bn_dllinstance,"ordereddither4"); orderedditherline2 = (ORDEREDDITHERLINE2)GetProcAddress(bn_dllinstance,"orderedditherline2"); orderedditherline4 = (ORDEREDDITHERLINE4)GetProcAddress(bn_dllinstance,"orderedditherline4"); if(ordereddither2 == NULL || ordereddither4 == NULL || orderedditherline2 == NULL || orderedditherline4 == NULL) { char buffer[512]; sprintf(buffer,"DLLファイル bluenoisedll.dll(or bluenoiseutf8dll) のバージョンが異なります\n"); AfxMessageBox(buffer,MB_OK | MB_ICONEXCLAMATION); FreeLibrary(bn_dllinstance); return(2); } // .... // 解放 FreeLibrary(bn_dllinstance); }
// m_editresultにbluenoise系列を1000個設定してエディットボックス等に表示する void CDlgBluenoise::OnBnClickedMakebluenoise100() { m_editresult = ""; char buffer[1024]; for(int i = 0 ; i < 1000 ; i++) { if(i % 10 == 0) { sprintf(buffer,"(%03d)",i / 10); m_editresult += buffer; } if(i % 10 == 9) { sprintf(buffer,"%10d\r\n",bluenoise()); } else { sprintf(buffer,"%10d, ",bluenoise()); } m_editresult += buffer; } UpdateData(FALSE); }新規のマトリクス(通常は、初期サイズである256×256よりも大きいサイズ)setbluenoisematrix()の呼び出しは以下の通り行う。
// 下記サンプルプログラムにおけるフォルダは"g:/tmp/"であるが、通常は他のフォルダを設定する。
// m_editsizeには512~16384の範囲の値が入る void CDlgBluenoise::OnBnClickedSetsize() { UpdateData(TRUE); if(m_editsize == 256) { setbluenoisematrix("",m_editsize); } else { setbluenoisematrix("g:\\tmp\\",m_editsize); } UpdateData(FALSE); }
// 1...ordered dither utility // do ordered dither (for grayscale image only) // for multiplane image(ex. RGB,CMYK), use class library or add API to this library. // input // int width; image width(pixel) // int height; image height(pixel) // int scanlinesize1; scanline size(byte count) of one line image // unsigned char* pdata1; 256 level image // int scanlinesize2; scanline size(byte count) of 2 or 4 level image // output // unsigned char* pdata2; 2 or 4 level image(one pixel is one byte) // 2 level has value(0,255) // 4 level has value(0,85,170,255) // return value // 0>...error(INITIALIZE_ERROR...initialize error(can not make instance of class library : memory shortage) // error(FILE_OPEN_ERROR....can not save or load bluenoise matrix data) // (MEMORY_SHORTAGE..memory shortage) // this library read "sizexsizeraw.dat" in folder specified by setbluenoisematrix() // If "size" is 1024, file name is "1024x1024raw.dat" // If "sizexsizeraw.dat" does not exist, setbluenoisematrix() API genarates the file automatically. // If value of "size" becomes bigger, quality of dithering image becomes higher. typedef int (__stdcall* ORDEREDDITHER2)(int width,int height,int scanlinesize1,unsigned char* pdata1,int scanlinesize2,unsigned char* pdata2); extern ORDEREDDITHER2 ordereddither2; typedef int (__stdcall* ORDEREDDITHER4)(int width,int height,int scanlinesize1,unsigned char* pdata1,int scanlinesize2,unsigned char* pdata2); extern ORDEREDDITHER4 ordereddither4; // ordered dither utility // line by line process // INPUT // int y; line no(0,...height - 1) typedef int (__stdcall* ORDEREDDITHERLINE2)(int width,int y,unsigned char* pdata1,unsigned char* pdata2); extern ORDEREDDITHERLINE2 orderedditherline2; typedef int (__stdcall* ORDEREDDITHERLINE4)(int width,int y,unsigned char* pdata1,unsigned char* pdata2); #extern ORDEREDDITHERLINE4 orderedditherline4;
// 1...組織的ディザリングユーティリティ // グレイスケールイメージに対する組織的ディザリングを実行する // マルチプレーン画像(ex. RGB,CMYK)を対象とした組織的ディザリングは、C++クラスライブラリでサポートしている。 // マルチプレーン画像に対しては、クラスライブラリを使うか、本ライブラリのAPIを拡張する必要がある。 // 入力 // int width; 画像の幅(pixel) // int height; 画像の高さ(pixel) // int scanlinesize1; pdata1のスキャンラインサイズ(byte) 一行の画像のバイト数 // unsigned char* pdata1; 256階調画像(1ピクセル1バイト) // int scanlinesize2; pdata2のスキャンラインサイズ(byte) 一行の画像のバイト数 // output // unsigned char* pdata2; 2 あるいは 4 階調画像(1ピクセル1バイト) // 2 階調の場合は(0/255の2値) // 4 階調の場合は(0/85/170/255の4値) // return value // 負値...エラー(myerrcode.h : INITIALIZE_ERROR...初期化エラー(クラスライブラリのインスタンス作成失敗 : 主にメモリ不足が原因) // エラー(myerrcode.h : FILE_OPEN_ERROR....ブルーノイズデータの保存、読込失敗(生成したブルーノイズ数列を書き込めない、読み込めない) // (myerrcode.h : MEMORY_SHORTAGE....メモリ不足) // 本ライブラリは、setbluenoisematrix()APIで指定したフォルダに"sizexsizeraw.dat"というファイル名でファイルを保存/読込する。 // たとえば"size"が1024の場合、ファイル名は"1024x1024raw.dat" // ファイルが無い場合、setbluenoisematrix()内部で自動的にブルーノイズを作成して"sizexsizeraw.dat"というファイル名で保存する // "size"の値が大きいほど、ディザリングの画質は良くなる typedef int (__stdcall* ORDEREDDITHER2)(int width,int height,int scanlinesize1,unsigned char* pdata1,int scanlinesize2,unsigned char* pdata2); extern ORDEREDDITHER2 ordereddither2; typedef int (__stdcall* ORDEREDDITHER4)(int width,int height,int scanlinesize1,unsigned char* pdata1,int scanlinesize2,unsigned char* pdata2); extern ORDEREDDITHER4 ordereddither4; // 組織的ディザリング // 1行単位でディザリング(プリンタドライバ中で1行ずつディザリングするなど) // 入力 // int y; 行番号(0~height - 1) typedef int (__stdcall* ORDEREDDITHERLINE2)(int width,int y,unsigned char* pdata1,unsigned char* pdata2); extern ORDEREDDITHERLINE2 orderedditherline2; typedef int (__stdcall* ORDEREDDITHERLINE4)(int width,int y,unsigned char* pdata1,unsigned char* pdata2); #extern ORDEREDDITHERLINE4 orderedditherline4;
int width = mppimage[0]->mgetrawwidth(); // 元の256階調グレイスケールイメージの幅(ピクセル) int height = mppimage[0]->mgetrawheight(); // 元の256階調グレイスケールイメージの高さ(ピクセル) int scanlinesize = mppimage[0]->mgetrawscanlinesize(); // 元の256階調グレイスケールイメージのスキャンラインサイズ(バイト) unsigned char* pdata1 = mppimage[0]->mgetrawdata(); // 元の256階調グレイスケールイメージ(scanlinesize * heightバイト) unsigned char* pdata2 = (unsigned char*)malloc(scanlinesize * height); // 2/4階調ディザリンググレイスケールイメージ(scanlinesize * heightバイト) // 2階調の場合、輝度値は0/255 // 4階調の場合、輝度値は0/85/170/255 if(pdata2 != NULL) { ordereddither2(0,width,height,scanlinesize,pdata1,scanlinesize,pdata2); free(pdata2); }ライン処理のサンプルプログラム
int width = mppimage[0]->mgetrawwidth(); // 元の256階調グレイスケールイメージの幅(ピクセル) int height = mppimage[0]->mgetrawheight(); // 元の256階調グレイスケールイメージの高さ(ピクセル) int scanlinesize = mppimage[0]->mgetrawscanlinesize(); // 元の256階調グレイスケールイメージのスキャンラインサイズ(バイト) unsigned char* pdata1 = mppimage[0]->mgetrawdata(); // 元の256階調グレイスケールイメージ(scanlinesize * heightバイト) unsigned char* pdata2 = (unsigned char*)malloc(scanlinesize * height); // 2/4階調ディザリンググレイスケールイメージ(scanlinesize * heightバイト) // 2階調の場合、輝度値は0/255 // 4階調の場合、輝度値は0/85/170/255 if(pdata2 != NULL) { for(int i = 0 ; i < height ; i++) { unsigned char* ps1 = pdata1 + i * scanlinesize; unsigned char* ps2 = pdata2 + i * scanlinesize; orderedditherline4(0,width,i,ps1,ps2); } free(pdata2); }