人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

画像の作成についての質問です。添付させていただいた画像は128×128pixelの画像でペイントでキャンバスのサイズを指定した後にテキストでABC(フォントは14でTime new roman)と書いた後に色の反転をした画像です。例えばこれをAAA~ZZZまで変化させて26の3乗個の画像を作り出す、もしくは手に入れるにはどのようにするのが効率良いのでしょうか?アイデアがある方はよろしくお願い申し上げます。フォントなどは気にしていませんので、アルファベットが並んだ画像を手に入れるのが目的です。真に申し訳ないのですが当方マクロなどの知識がなく、できれば簡単にできる方法を教えていただけると助かります。プログラミングに関してはC言語でしたら一通り使えると思います。どうかよろしくお願いいたします。

1200392959
●拡大する

●質問者: jsakato
●カテゴリ:コンピュータ 科学・統計資料
✍キーワード:AAA ABC C言語 roman Time
○ 状態 :終了
└ 回答数 : 2/2件

▽最新の回答へ

1 ● khoshi3
●50ポイント

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,-)の中より、任意に指定して、 固定的に表示することができます。

◎質問者からの返答

ご回答いただきありがとうございました。

これを機にCGIも勉強してみようと思います。またの機会がありましたら是非よろしくお願いいたします。


2 ● Mook
●150ポイント ベストアンサー

下記に参考になるサイトがありました。

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;
}
◎質問者からの返答

ご回答ありがとうございます。ご提示していただきましたプログラムを実行しましたところビットマップファイルは作成されるのですが、開く事ができませんでした。いくつかのフォトタッチソフトで開く事を試みましたが「デコードエラー」「ストリームからの読み込みエラー」などの表示が出て読み込む事ができませんでした。お手数おかけしますが当方には原因が分からないので解決策を教えていただけると助かります。

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ