GAEjでお絵かき

Google App Engine(以下、GAE)上で、アップロードした絵に文字を入れてくれる掲示板を作ろうかなと思っている。


GAEではJavaの画像処理関係のライブラリはほとんど削られているが、いくつかの画像を合成する機能ぐらいは持っている。
しかしながら、1万文字以上もある日本語文字を全て画像として用意するわけにもいかない。
また、画像として文字を用意するのであれば、容量が大きくなるか、クオリティが低くなるか。
1文字ごとに別ファイルにして1万ファイルというのは、GAE上にアップ可能な静的ファイルの数制限に引っかかるので、1つのファイル内に複数の文字を収納する必要がある。
あるいはストレージ上に文字画像データを持たせることだが、やはりどうにも、非現実的な気がするのだ。


そこで、GAE上でフォントファイルを使って文字画像を生成しようというのが、今の所の予定。


フォントファイル描画は、この辺↓を見て勉強することにする。
http://vanilla-room.cocolog-nifty.com/


で、とりあえず32bitBitMapの最上位バイトが不透明度αとして認識されるかどうかを調べるために、以下の様な超簡易お絵かき画像作成クラスを作って実験してみた。

public class Canvas {
	int width;
	int height;
	int[][] img;
	public Canvas(int width, int height) {
		this.width = width;
		this.height = height;
		this.img = new int[height][width];
	}
	public void setPixel(int x, int y, int color) {
		if(0<=x && x<width && 0<=y && y<height) {
			img[y][x] = color;
		}
	}
	public int getPixel(int x, int y) {
		if(0<=x && x<width && 0<=y && y<height) {
			return img[y][x];
		}
		return 0;
	}
	public byte[] toData() {
		int offset = 26;
		int fsize = width * height * 4 + offset;
		byte[] data = new byte[fsize];
		data[0] = (byte)'B';
		data[1] = (byte)'M';
		data[2] = (byte)(fsize);
		data[3] = (byte)(fsize >> 8);
		data[4] = (byte)(fsize >> 16);
		data[5] = (byte)(fsize >> 24);
		data[6] = (byte)0;
		data[7] = (byte)0;
		data[8] = (byte)0;
		data[9] = (byte)0;
		data[10] = (byte)offset;
		data[11] = (byte)(offset >> 8);
		data[12] = (byte)(offset >> 16);
		data[13] = (byte)(offset >> 24);
		data[14] = (byte)12;
		data[15] = (byte)0;
		data[16] = (byte)0;
		data[17] = (byte)0;
		data[18] = (byte)(width);
		data[19] = (byte)(width>>8);
		data[20] = (byte)(height);
		data[21] = (byte)(height>>8);
		data[22] = (byte)1;
		data[23] = (byte)0;
		data[24] = (byte)32;
		data[25] = (byte)0;
		int i = offset;
		for(int y = height-1; 0<=y; --y) {
			for(int x = 0; x<width; ++x) {
				int c = img[y][x];
				data[i++] = (byte)(c);
				data[i++] = (byte)(c>>8);
				data[i++] = (byte)(c>>16);
				data[i++] = (byte)(c>>24);
			}
		}
		return data;
	}
}


結果、ちゃんと不透明度αとして認識された。


お絵かきする上では、32bitフルカラーはちょい重たい気がするので、8bitのパレット画像(この場合、OS/2のbitmapだとパレット色は24bit表現なので、windowsのbitmapにして32bit表現のパレット色にする)で最終的に作るかもしれない。


で、後は直線及びベジェ曲線で囲まれた領域の塗りつぶしアルゴリズムを実装して、フォントファイルのフォーマットを解析すれば、なんとかなりそうな感じです。