少し前から「プレーンテキストの画像形式」というものを探していた。
レイトレーシングなど、絵が出力結果であるプログラムを作って遊んでいると、レンダリングの結果を出す先に困ることがある。
画面表示のできるライブラリを持ってくるのも大仰だ。画像に保存したいところだ。しかも、printfとかで適当に。
BMPの構造体の定義や、PNGやGIFのアルゴリズムを空で書き下すには修行が必要だ。(windows.hは反則)
UNIX系列であればPNMというかなり理想的な形式がある。しかし、残念ながらWindows付属のビューアでは見られない。
SVG形式も考えたが、これはビットマップには向かない。rectを一面に並べる変換器を作ってみたら200KB程度の画像が9MBに膨れ上がった。
サイズはテキストの時点である程度諦めるべきところだが、どちらにしろ表示が極端に重たかった。
SVGの形式を眺めていて、HTMLで一時期流行った遊びを思い出した。
「tableタグでbgcolorを指定したtdをひたすら並べる」
<code><html> <head> <style> tr{height:1px} td{width:1px} </style> </head> <body> <table border="0" cellpadding="0" cellspacing="0"> <tr><td bgcolor="#000000"></td><td bgcolor="#000000"></td><td bgcolor="#000000"></td><td... <tr><td bgcolor="#000000"></td><td bgcolor="#000000"></td><td bgcolor="#000000"></td><td... ... </table> </body> </html> </code>
本当にfprintfしか使わない実装。
void dump(int w, int h, const char *pixels, FILE *fp) { int x, y; fprintf(fp, "<html><head><style>tr{height:1px}td{width:1px}</style></head><body><table cellpadding=0 cellspacing=0 width=%d height=%d>", w, h); for(y=0; y<h; y++) { fprintf(fp, "<tr>"); for(x=0; x<w; x++) { fprintf(fp, "<td bgcolor=#%02x%02x%02x></td>", pixels[x + y * w], pixels[x + y * w + 1], pixels[x + y * w + 2]); } fprintf(fp, "</tr>"); } fprintf(fp, "</body></html>"); }
これでとりあえずブラウザに表示させてプリントスクリーンすれば画像になる。
いまどきならCanvasでImageDataなどを使うのかもしれない。
(copied from tumblr)