3

C# プログラムにピクセルの配列があり、intそれを画像に変換したいと考えています。問題は、プログラムの Java ソース コードを同等の C# コードに変換していることです。Java では、int ピクセルの配列を画像に表示する行を読み取ります。

Image output = createImage(new MemoryImageSource(width, height, orig, 0, width));

誰かがC#に相当するものを教えてもらえますか?

ここで orig はintピクセルの配列です。Bitmapクラスを検索したところ、呼ばれるメソッドSetPixelがありますが、問題はax、y座標番号を取ることです。しかし、私のコードにはintピクセルの配列があります。もう1つの奇妙なことは、元の配列に負の数があり、それらが255から遠く離れていることです.Javaではこれは同じケースです(C#とJavaの配列の両方が同等の値を持つことを意味します)Javaでは値が正常に機能しています。

しかし、その行を C# に変換できません。助けてください。

4

6 に答える 6

6

WPF を使用すると、配列から直接ビットマップ (イメージ) を作成できます。次に、この画像をエンコードしたり、表示したり、遊んだりできます。

int width = 200;
int height = 200;

//
// Here is the pixel format of your data, set it to the proper value for your data
//
PixelFormat pf = PixelFormats.Bgr32;
int rawStride = (width * pf.BitsPerPixel + 7) / 8;

//
// Here is your raw data
//
int[] rawImage = new int[rawStride * height / 4];


//
// Create the BitmapSource
//
BitmapSource bitmap = BitmapSource.Create(
    width, height,
    96, 96, pf, null,
    rawImage, rawStride);
于 2008-12-24T23:34:24.830 に答える
2

私はすでに提示されているWPFオプションが好きですが、ここでは使用していLockBitsますBitmap

        // get the raw image data
        int width, height;
        int[] data = GetData(out width, out height);

        // create a bitmap and manipulate it
        Bitmap bmp = new Bitmap(width,height, PixelFormat.Format32bppArgb);
        BitmapData bits = bmp.LockBits(new Rectangle(0, 0, width, height),
            ImageLockMode.ReadWrite, bmp.PixelFormat);
        unsafe
        {
            for (int y = 0; y < height; y++)
            {
                int* row = (int*)((byte*)bits.Scan0 + (y * bits.Stride));
                for (int x = 0; x < width; x++)
                {
                    row[x] = data[y * width + x];
                }
            }
        }
        bmp.UnlockBits(bits);

(テストデータとして):

    public static int[] GetData(out int width, out int height)
    {
        // diagonal gradient over a rectangle
        width = 127;
        height = 128;
        int[] data =  new int[width * height];
        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                int val = x + y;
                data[y * width + x] = 0xFF << 24 | (val << 16) | (val << 8) | val;
            }
        }
        return data;
    }
于 2008-12-26T11:12:03.283 に答える
2

Bitmap.LockBitsを使用して、SetPixel 経由ではなく、直接操作できるビットマップ データを取得できます。(ロックビットの使い方)

于 2008-12-24T23:24:53.463 に答える
1

さて、私は各 int が複合 ARGB 値であると仮定していますか? 簡単なオプションがない場合は、LockBitsを検討する価値があります。これは よりもはるかSetPixelに高速ですが、より複雑です。また、int がどのように構成されているかを確認する必要があります (ARGB? RGBA?)。もっと明確なオプションがあるかどうかを確認しようとします...

于 2008-12-24T23:25:27.330 に答える
0

LockBits を使用することをお勧めしますが、より遅い SetPixel ベースのアルゴリズムは次のようになります


// width - how many int's per row        
// array - array of integers
Bitmap createImage(int width, int[] array)
{            
  int height = array.Length / width;
  Bitmap bmp = new Bitmap(width, height);
  for (int y = 0; y < height; y++)
  {
    for (int x = 0; x < array.Length; x += width)
    {
      bmp.SetPixel(x, y, Color.FromArgb(array[i]));
    }
  }
  return bmp;
}
于 2008-12-24T23:37:29.677 に答える
0

MemoryImageSourceのコンストラクターの 3 番目の引数は、その順序で argb 値で構成される int の配列です

そのページの例では、次の方法でそのような配列を作成しています。

pix[index++] = (255 << 24) | (red << 16) | blue;

その整数配列をバイト配列に分解する必要がありますが (シフト演算子が便利です)、LockBits メソッドが機能するためには bgr の順序にする必要があります。

于 2008-12-24T23:44:30.803 に答える