次の2つのルーチンを考えてみましょう。ビットマップからint [、]への変換とその逆
//Tested
///Working fine.
public static Bitmap ToBitmap(int [,] image)
{
int Width = image.GetLength(0);
int Height = image.GetLength(1);
int i, j;
Bitmap bitmap = new Bitmap(Width, Height);
BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, Width, Height),
ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
unsafe
{
byte* address = (byte*)bitmapData.Scan0;
for (i = 0; i < bitmapData.Height; i++)
{
for (j = 0; j < bitmapData.Width; j++)
{
// write the logic implementation here
address[0] = (byte)image[j, i];
address[1] = (byte)image[j, i];
address[2] = (byte)image[j, i];
address[3] = (byte)255;
//4 bytes per pixel
address += 4;
}//end for j
//4 bytes per pixel
address += (bitmapData.Stride - (bitmapData.Width * 4));
}//end for i
}//end unsafe
bitmap.UnlockBits(bitmapData);
return bitmap;// col;
}
//Tested
///Working fine.
public static int[,] ToInteger(Bitmap bitmap)
{
int[,] array2D = new int[bitmap.Width, bitmap.Height];
BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
ImageLockMode.ReadWrite,
PixelFormat.Format32bppRgb);
unsafe
{
byte* address = (byte*)bitmapData.Scan0;
int paddingOffset = bitmapData.Stride - (bitmap.Width * 4);//4 bytes per pixel
for (int i = 0; i < bitmap.Width; i++)
{
for (int j = 0; j < bitmap.Height; j++)
{
byte[] temp = new byte[4];
temp[0] = address[0];
temp[1] = address[1];
temp[2] = address[2];
temp[3] = address[3];
array2D[j, i] = BitConverter.ToInt32(temp, 0);
//4-bytes per pixel
address += 4;//4-channels
}
address += paddingOffset;
}
}
bitmap.UnlockBits(bitmapData);
return array2D;
}
これらの2つのルーチンは、32bppイメージで正常に動作します。これらのルーチンは、ピクセル形式がPixelFormat.Format32bpp
に設定されている場合にのみ機能します。 PixelFormat.Format8bppIndexed
を使用すると、例外が生成されます。 、Iが32ビットBitmap
にすることが階調をint[,]
バック変換するたびに変換する必要がある(また、Iはbyte
及びためのアドレス計算の問題のint
間のシームレスな変換を達成することができなかった)その例外を回避するために
Bitmap
に私はこの問題を取り除きたい。
Bitmap grayscale = Grayscale.ToGrayscale(InputImage);
//Here, the Bitmap is treated as a 32bit image
//to avoid the exception eventhough it is already
//an 8bpp grayscale image.
int[,] i1 = ImageDataConverter.ToInteger(grayscale);
Complex[,] comp = ImageDataConverter.ToComplex(i1);
int[,] i2 = ImageDataConverter.ToInteger(comp);
Bitmap b2 = ImageDataConverter.ToBitmap(i2);
//It is already a Grayscale image.
//But, the problem is, b2.PixelFormat is set to
//PixelFormat.Formap32bpp because of those routines.
//Hence the unnecessay conversion.
b2 = Grayscale.ToGrayscale(b2);
8bppインデックス付き(グレースケール)イメージでのみ動作するように修正する必要があります。
どうすれば実現できますか?
あなたはどのような操作をしたいですか?あなたは 'int [、]'の代わりに 'byte [、]'を渡すことを望んでいるのですか?そうでなければ、 'int [、]'はどのように解釈されますか?各32ビット値は0から255の間の値を保存するだけでしょうか?彼らは実際にあなたが書くように索引付けされていますか?もしそうなら、どんなパレットを使うべきですか?または、彼らは本当にグレースケールですか(あなたも書いたように)?各32ビット値に4つのピクセルがパックされますか?いずれにしても、8ビットの値はどのように解釈されますか? 32bppイメージを出力するか、出力も8bppにする必要がありますか?あなたは、仕様の重要な部分をすべて除外しました。 –