C#で64bitPNGを出したかったので、やってみた。
using (Bitmap bmp = new Bitmap(256, 256, PixelFormat.Format64bppArgb))
{
BitmapData bmd = bmp.LockBits(
new Rectangle(Point.Empty, bmp.Size),
ImageLockMode.WriteOnly,
PixelFormat.Format64bppArgb);
for (int y = 0; y < bmp.Height; y++)
{
for (int x = 0; x < bmp.Width; x++)
{
int l = y + x;
byte[] data = BitConverter.GetBytes((UInt16)l);
int pos = x * 8 + bmd.Stride * y;
Marshal.WriteByte(bmd.Scan0, pos + 0, data[0]);
Marshal.WriteByte(bmd.Scan0, pos + 1, data[1]);
Marshal.WriteByte(bmd.Scan0, pos + 2, data[0]);
Marshal.WriteByte(bmd.Scan0, pos + 3, data[1]);
Marshal.WriteByte(bmd.Scan0, pos + 4, data[0]);
Marshal.WriteByte(bmd.Scan0, pos + 5, data[1]);
Marshal.WriteByte(bmd.Scan0, pos + 6, 255);
Marshal.WriteByte(bmd.Scan0, pos + 7, 255);
}
}
bmp.UnlockBits(bmd);
bmp.Save("./log.png", ImageFormat.Png);
}
まずBitmapのコンストラクタにPixelFormat.Format64bppArgbを指定する。これで64bitの画像が作れる。
あとは色を載せるだけだが、今回は直接値を書き込んでいる。
試してないが、たぶんSetPixelはダメだと思う。Color.FromArgbだと256以上は例外が投げられるはずなので、16bit画像は作れないはず(未確認)。
画像を保存する際は、ImageFormat.Pngで保存すれば、16bitのPNG(16bit*RGBA =64bit)で保存される。
ちなみに、このサンプルは下位9bitだけを使ってグレースケール画像を生成している。8bit換算で下位約2bitしか操作していないから、普通に表示しても何も見えない。
これをpaint.netで輝度をいじると以下のような感じ。
下位8bitが切り捨てられて、上位8bitのみが使用されている。
Lr5で輝度をいじると以下のような感じ。
てきとーに調整したのでガタガタだが、ちゃんとグレースケールで表示されてる。つまり、少なくとも下位8bitの内の数bitは使用されている。
ということで、天体写真合成で16bitの出力ができる目処が立ったので、あとから輝度を調整しやすくなった。
もともと自前で48bitPNGを出すライブラリを作ろうと思ってて、PNGって面倒くさいな~と思ってたところなので、.Net単体で簡単に64bitが出せたので楽になった。
BitmapDataを使わなきゃいけないのは面倒だけど、そもそもBitmap.SetPixelはクッソ遅いので、どっちにしろ自前でBitmapDataの処理は作らにゃいかん。
僕としては96bitPNGが欲しいところw。 16bitだと256枚加算まではロスレスだが、それ以上の枚数を重ねると情報が劣化してしまう。96bitだと8bit画像を16777216枚まで重ねられるので、当面は心配いらない。いちおうPNGのヘッダは1024bppまで対応しているっぽいけど、.Netは64bppが上限のはず。
一般的なユーザーでは32bppPNGで充分だろうけども、データ処理の中間データとして使うならやはり128bppPNGくらいあると心強い。あとはIntだけじゃなくてFloatを持てたりとか、1/3/4ch以外にも、任意のch数を持てたりとかすると、学術データの標準フォーマットとして使えると思うんだけど。
APNGのフォーマットは調べたことがないが、このコンテナに入れれば2次元画像をもう1次元増やせるので、3次元空間に4次元のベクトルをもたせることができる。現状だと、3次元空間に16bitの4次元ベクトルを入れるのが限界かな。それでも大したもんだが。16bit整数から浮動小数点に変換する処理とかを入れればさらに情報量は増やせる。
APNGだとWebブラウザでも表示できるから、3次元空間の3次元ベクトルデータをざっくりと確認するのにWebブラウザで開けばいい、という利点もあるかも?
PNG、クッソ古い規格なのに、拡張性やばい。