自分がよく使う画像ファイルは24bitカラーの画像が多いのですが、画像加工用のファイルなどはRGBにアルファチャンネルの8bitを加えて32bitにしています。
疑問に思ったのは、GIMPを使ってグレースケール画像をエクスポートした場合、何bitになるのでしょうか?あまり意識する場面はなかったのですが.NetFrameworkのbitmapオブジェクトを作ろうとPixelFormatをセットしようとしたところ、はて何を選べばよいのかと迷った次第でございます。
PixelFormatの一覧を見てもそれらしい値が見つかりません。グレーというワードも見受けられないので、なんとなく想像もできるのですが確認したいと思いうます。
ネットで情報を調べるのもよいですが、実際画像ファイルを作ってどうなっているか試してみたいと思います。
GIMPで新規画像をグレースケールで作成しアルファチャンネル付きのpng形式でエクスポートしてみます。
エクスプローラーでファイルのプロパティを見てみるとビットの深さは32bitと表示されていました。
ということは32bitのARGBでRGBには各チャンネルが同じ値がセットされているのではと予想します。
実際C#で簡単な検証プログラムを組んでみます。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
/*
画像ファイルのピクセルフォーマットを確認する。
*/
namespace checkpixelformat
{
class Program
{
static void CheckPixelFormat(string inFile)
{
bool neFlag = false;
using (var bmp = new Bitmap(inFile))
{
Console.WriteLine("{0}", bmp.PixelFormat.ToString());
var bmpd = bmp.LockBits(
new Rectangle(0, 0, bmp.Width, bmp.Height),
ImageLockMode.ReadWrite,
bmp.PixelFormat
);
var byteWidth = (int)(bmpd.Stride / bmp.Width);
byte[] pixels = new byte[bmpd.Stride * bmp.Height];
System.Runtime.InteropServices.Marshal.Copy(bmpd.Scan0, pixels, 0, pixels.Length);
// 先頭からループ
for (int y = 0; y < bmp.Height; y++)
{
for (int x = 0; x < bmpd.Width; x++)
{
int pos = y * bmpd.Stride + x * byteWidth;
if ((pixels[pos] != pixels[pos+1]) || (pixels[pos] != pixels[pos+2]))
{
neFlag = true;
}
}
}
bmp.UnlockBits(bmpd);
}
Console.Write("RGBの各チャンネルの値は");
if (neFlag)
{
Console.WriteLine("異なる");
} else {
Console.WriteLine("同じ");
}
}
static void Main(string[] args)
{
if (args.Length == 0)
{
return;
}
var inFile = args[0];
CheckPixelFormat(inFile);
}
}
}
結論としてPixcelFormatはFormat32bppArgbでした。またRGBの各チャンネルは各座標同じ値がセットされていました。
8bitの情報を24bitに格納しているので容量的に効率が悪い話ではありますが、無圧縮のBMPファイルとかを選ばなければ大概圧縮されたファイル形式なので容量的に問題になりずらいだと思います。
コメント