0

winformsのpictureBoxに入れたい640x480の画像データフレームを吐き出すUSBビデオカメラがあります。SetPixel を使用してデータを pictureBox にマップすると、画像はきれいに見えますが、SetPixel は非常に遅いので、代わりにこれを試しました。

    void CreateBitmap()
    {
        int width = bitmap.Width;
        int height = bitmap.Height;
        int n = 0;

        // copy normalized data into 1D array
        lock (imageDataLocker)
        {
            for (int i = 0; i < width; ++i)
            {
                for (int j = 0; j < height; ++j)
                {
                    Color c = Colorizer.GetColor(imageData[i, j]);
                    rgbValues[n] = c.R;
                    rgbValues[n + 1] = c.G;
                    rgbValues[n + 2] = c.B;
                    n += 3;
                }
            }
        }

        // Copy image data into the bitmap
        Rectangle rect = new Rectangle(0, 0, width, height);
        BitmapData bitmapData = bitmap.LockBits(rect, ImageLockMode.WriteOnly, bitmap.PixelFormat);
        IntPtr ptr = bitmapData.Scan0;
        int bytes = rgbValues.Length;
        System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
        bitmap.UnlockBits(bitmapData);
    }

ここで、rgbValues は 1 ピクセルあたり 3 バイトを含む 1D バイト配列、imageData はカメラによって提供される 2D int 配列、bitmap は 24bppRgb 形式です。これでエラーは発生しませんが、pictureBox の BackgroundImage にビットマップを割り当てると、奇妙なバンディング効果があります。

ウェブカメラ

ここで何が欠けていますか?

4

1 に答える 1

1

まず第一に、外側のループは j=0; であるべきだと思います。j

左半分が青、右半分が黒のビットマップを作成するこの単純なパターンでこれをテストしました。

        Bitmap bm = new Bitmap(16, 16, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

        BitmapData bitmapData = bm.LockBits(new Rectangle(0,0,16,16), ImageLockMode.WriteOnly, bm.PixelFormat);
        IntPtr ptr = bitmapData.Scan0;

        byte[] rgbValues = new byte[16 * 16 * 3];

        int b = 0;

        for (int y = 0; y < bm.Height; y++)
        {
            for (int x = 0; x < bm.Width; x++)
            {
                if (x < 7)
                {
                    rgbValues[b++] = 255; // BLUE, not red!
                    rgbValues[b++] = 0; // g
                    rgbValues[b++] = 0; // r
                }
                else
                {
                    rgbValues[b++] = 0; // r
                    rgbValues[b++] = 0; // g
                    rgbValues[b++] = 0; // b

                }
            }
        }

        int bytes = rgbValues.Length;
        System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
        bm.UnlockBits(bitmapData);
        pictureBox1.Image = bm;

    }

また、書き込む最初のバイトは BLUE コンポーネント、次に緑、赤の順であることに注意してください。

于 2012-05-15T16:45:38.613 に答える