下記に参考になるサイトがありました。
http://codezine.jp/a/article/aid/1643.aspx?p=2
フォントのサイズ(pt)は画像解像度が決まらないとピクセルへの変換ができないので、今回は128ピクセルに対して、全体が収まるサイズを優先しました。
上に紹介されたページに掲載されたコードを変更しただけですが、下記のコードで一応質問された内容の結果になるかと思います。
下記はA~Cの範囲で作成するようになっているので、CをZにすれば 26^3 の画像を生成します。
(一応 Borland のコンパイラで動作確認済みです。)
#include<stdio.h> #include<windows.h> #include<stdlib.h> #include<string.h> #define IMAGE_SIZE 128 #define FONT_SIZE 48 //BITMAPINFO構造体を再定義 //モノラルビットマップなので、RGBQUAD構造体配列の長さは2 typedef struct tagMYBITMAPINFO{ BITMAPINFOHEADER bmiHeader; RGBQUAD bmiColors[2]; }MYBITMAPINFO; //RGBQUAD構造体配列 int Colors[2] = { 0x00000000, //黒 0x00FFFFFF, //白 }; //画像データのサイズを取得する関数 //4バイト(32ビット)区切りになるようにする //4バイト(32ビット)のブロックがいくつになるか計算して、 //4と高さを掛ける int GetSizeImage(int size){ return ((size- 1) / 32 + 1) * 4 * size; } //フォント作成用関数 HFONT CreateMyFont(unsigned char *FontName,int FontSize){ LOGFONT lf; ZeroMemory(&lf,sizeof(LOGFONT)); lf.lfHeight = FontSize; lf.lfWidth = 0; lf.lfEscapement = 0; lf.lfOrientation = 0; lf.lfWeight = 0; lf.lfItalic = 0; lf.lfUnderline = 0; lf.lfStrikeOut = 0; lf.lfCharSet = DEFAULT_CHARSET; lf.lfOutPrecision = OUT_DEFAULT_PRECIS; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfQuality = DEFAULT_QUALITY; lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; lstrcpy(lf.lfFaceName,FontName); return CreateFontIndirect(&lf); } //文字描画関数 //Unicode(UTF-16)をいったん文字列に変換してから //TextOutWで文字を出力する void DrawChar(HDC hdc,wchar_t *ws,int FontSize){ SIZE size; //半角文字を考慮して中央に描画する GetTextExtentPoint32W(hdc, ws, lstrlenW(ws),&size); TextOutW(hdc,(FontSize - size.cx) / 2, ( IMAGE_SIZE - FONT_SIZE ) / 2 ,ws,lstrlenW(ws)); } //BITMAPFILEHEADER構造体をセットする関数 void SetBitmapFileHeader(BITMAPFILEHEADER *lpbmpfh,int SizeImage){ int OffBits;//画像データまでのオフセット OffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(Colors); ZeroMemory(lpbmpfh,sizeof(BITMAPFILEHEADER)); lpbmpfh->bfType = 0x4D42; //BM lpbmpfh->bfSize = OffBits + SizeImage; lpbmpfh->bfOffBits = OffBits; } //BITMAPINFOHEADER構造体をセットする関数 void SetBitmapInfoHeader(BITMAPINFOHEADER *lpbmpih, int SizeImage, int FontSize){ ZeroMemory(lpbmpih,sizeof(BITMAPINFOHEADER)); lpbmpih->biSize = 40; lpbmpih->biWidth = FontSize; //画像の幅・高さはFontSizeにする lpbmpih->biHeight = FontSize; lpbmpih->biPlanes = 1; lpbmpih->biBitCount = 1; //モノクロビットマップの場合は1 lpbmpih->biSizeImage = SizeImage; } //lpvBitsへ画像データを読み込む関数 void SetBitmapData(void *lpvBits, BITMAPINFOHEADER *lpbmpih, wchar_t *st, unsigned char *FontName ) { HDC hdcScreen,hdc; HBITMAP hBitmap,hBitmapOld; HFONT hFont,hFontOld; RECT rect; MYBITMAPINFO mybmpi; hdcScreen = GetDC(NULL); //スクリーンのデバイスコンテキストを取得 hdc = CreateCompatibleDC(hdcScreen); //スクリーン互換の //デバイスコンテキストを取得 hBitmap = CreateCompatibleBitmap(hdcScreen,IMAGE_SIZE,IMAGE_SIZE); //スクリーン互換のビットマップを作成 hBitmapOld = SelectObject(hdc,hBitmap); hFont = CreateMyFont(FontName,FONT_SIZE);//フォントを作成 hFontOld = SelectObject(hdc,hFont); //半角文字を考慮して、背景を白で埋めておく SetRect(&rect,0,0,IMAGE_SIZE, IMAGE_SIZE); FillRect(hdc,&rect,GetStockObject(WHITE_BRUSH)); DrawChar(hdc,st,IMAGE_SIZE);//文字を描画 //MYBITMAPINFO構造体をセット mybmpi.bmiHeader = *lpbmpih; memcpy(mybmpi.bmiColors,Colors,sizeof(Colors)); //lpvBitsへビットマップデータを読み込む GetDIBits(hdc,hBitmap,0,IMAGE_SIZE, lpvBits,(BITMAPINFO *)&mybmpi,DIB_RGB_COLORS); //以下、終了処理 DeleteObject(SelectObject(hdc,hBitmapOld)); DeleteObject(SelectObject(hdc,hFontOld)); DeleteDC(hdc); ReleaseDC(NULL,hdcScreen); } void CharCodeToBitmapFile(wchar_t *CharCode, unsigned char *FontName, unsigned char *FileName){ int SizeImage; BITMAPFILEHEADER bmpfh; BITMAPINFOHEADER bmpih; void *lpvBits; FILE *fp; //画像データのサイズを取得 SizeImage = GetSizeImage(IMAGE_SIZE); //BITMAPFILEHEADER構造体をセット SetBitmapFileHeader(&bmpfh,IMAGE_SIZE); //BITMAPINFOHEADER構造体をセット SetBitmapInfoHeader(&bmpih,SizeImage,IMAGE_SIZE); //バッファを用意 lpvBits = (void *)malloc(SizeImage); //画像データを読み込む SetBitmapData(lpvBits,&bmpih,CharCode,FontName); //ファイルへの書き込み fp = fopen(FileName,"wb"); fwrite(&bmpfh,sizeof(BITMAPFILEHEADER),1,fp); fwrite(&bmpih,sizeof(BITMAPINFOHEADER),1,fp); fwrite(Colors,sizeof(Colors),1,fp); fwrite(lpvBits,SizeImage,1,fp); fclose(fp); free(lpvBits);//バッファを解放 } int main(void){ wchar_t st[4]; wchar_t i, j, k; char file_name[32]; st[3] = '\0'; for ( i='A' ; i <= 'C' ; i++ ) { st[0] = i; for ( j='A' ; j <= 'C' ; j++ ) { st[1] = j; for ( k='A' ; k <= 'C' ; k++ ) { st[2] = k; sprintf( file_name, ".\\%c%c%c.bmp", (char)i, (char)j, (char)k ); printf( "make %s\n", file_name ); CharCodeToBitmapFile( st, "Time new roman",file_name ); } } } return 0; }
Gdライブラリを使うと、任意の文字列を含む画像を動的に生成できます。C言語での例は、下記URLのgdImageChar()のところを見てください。:
http://www2d.biglobe.ne.jp/~gama/cgi/gd/gd13.htm
perl用のモジュールもあり、perlのCGIから使えます。(わたしが使ったことがあるのはこっちです。):
http://x68000.q-e-d.net/~68user/webcgi/image-1.html
プログラムを書かずに済ます方法としては、アクセスカウンタをカウンタとして利用せず、任意の文字列を"lit="で表示させるようにするという方法もあると思います。
(AからZの1文字ずつのGIFファイルは準備する必要はあると思います。ただし、ご希望通りの128x128pixelの画像ではなくなります。)
http://www.exe.ne.jp/~staff/manual/counter.html
lit=X 文字列表示 (Display literal)
表示できる文字(0123456789:ap,-)の中より、任意に指定して、 固定的に表示することができます。
こちらでできたファイルは、ペイントでも画像ビューアでも見れるのですが、どのようなエラーメッセージでしょうか。
正確な内容を教えていただけますか。
お手数おかけして申し訳ございません。
まずペイントで開こうとしますと「メモリまたはリソースが足りないため、作業を完了できません。いくつかのプログラムを終了して、もう一度やり直してください。」と表示がされて開く事ができません。
Windows Picture and Fax Viewerでも「プレビューを利用できません」と表示され画像を開けませんでした。
irfan Viewで開こうとしますと「デコードエラーです。BMPは不正なファイルかサポートされていません。」と表示されて開く事ができませんでした。
もしかしたら、ヘッダ情報が正しく出力されていないかもしれないですね。
コンパイラは、何をお使いでしょうか。
生成されたファイルをバイナリエディタで、見たときにヘッダ情報はどのようになっていますか。
42 4D BE 00 00 00 00 00 00 00 3E 00 00 00 28 00
00 00 80 00 00 00 80 00 00 00 01 00 01 00 00 00
00 00 00 08 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 FF FF FF 00 FF FF
のようでしたら正しいはずですが。詳細は、下記を参照ください。
http://www.kk.iij4u.or.jp/~kondo/bmp/
これが違っているようなら、コンパイル時のオプションを確認してみてください(特にEndian関連)。
ご提示していただいたプログラムがとても参考になりました。
ありがとうございました。またの機会がありましたら是非よろしくお願いもうしあげます。
記念すべき100匹目のイルカ、ありがとうございました。