将像素数组转换为C#中的图像

时间:2008-12-24 23:13:54

标签: c# java arrays pixels

我的C#程序中有一个int像素数组,我想将其转换为图像。问题是我正在将程序的Java源代码转换为等效的C#代码。在java中,行读取将int像素数组显示为image:

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

有人可以告诉我C#的等价物吗?

这里的orig是int像素的数组。我搜索了Bitmap类,并且有一个名为SetPixel的方法,但问题是它需要一个x,y坐标数。但我的代码中有一个int像素数组。另一个奇怪的事情是我的orig数组有负数,它们远远超过255.在Java中这是相同的情况(意味着C#和Java中的数组具有相同的值)并且值在Java中正常工作。

但我无法将该行转换为C#。请帮忙。

6 个答案:

答案 0 :(得分: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);

答案 1 :(得分:2)

您可以使用Bitmap.LockBits获取可以直接操作的位图数据,而不是通过SetPixel。 (How to use LockBits

答案 2 :(得分:2)

我喜欢已经提供的WPF选项,但这里使用的是LockBitsBitmap

        // 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;
    }

答案 3 :(得分:1)

好吧,我假设每个int都是复合ARGB值?如果没有一个简单的选项,那么LockBits可能值得一看 - 它会比SetPixel快得多,但更复杂。您还必须确保知道int的组成方式(ARGB?RGBA?)。我会试着看看是否有更明显的选择......

答案 4 :(得分: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;
}

答案 5 :(得分:0)

MemoryImageSource的构造函数的第三个参数是一个由argb值按顺序组成的int数组

该页面中的示例通过;

创建了这样的数组
pix[index++] = (255 << 24) | (red << 16) | blue;

你需要将整数数组分解为一个字节数组(移位运算符会很有用),但它应该是bgr顺序,以便LockBits方法有效。