グレースケールで保存したPNGのPixelFormatは何になる?

C# コンピュータ
C#

取り扱う画像ファイルはRGBがおのおの8bitで24bit画像が多いのですが、画像加工用のファイルなどはRGBにアルファチャンネルの8bitを加えて32bitとなります。
疑問に思ったのはグレースケールの場合、何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);
			
		}
	}
}

Format32bppArgb

ではアルファチャンネルはよいとして、RGBにはどんな値がセットされているでしょうか?予想では各チャンネル同じ値がセットされていると思われます。そちらも検証してみます。

RGBの各チャンネルの値は同じ

というわけでグレースケールは24bitカラーフォーマットでRGB各チャンネルに同じ値をセットすることで8bitで濃淡を表現しているようです。
8bitの情報を24bitに格納しているので容量的に効率が悪い話ではありますが、無圧縮のBMPファイルとかを選ばなければ大概圧縮されたファイル形式なので容量的に問題になりずらいだと思います。

コメント