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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/392324/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 01:44:13  来源:igfitidea点击:

Converting an array of Pixels to an image in C#

c#javaarrayspixels

提问by

I have an array of intpixels in my C# program and I want to convert it into an image. The problem is I am converting Java source code for a program into equivalent C# code. In java the line reads which displays the array of int pixels into image:

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

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

can someone tell me the C# equivalent?

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

Here orig is the array of intpixels. I searched the Bitmap class and there is a method called SetPixelbut the problem is it takes a x,y coordinate number. But what I have in my code is an array of intpixels. Another weird thing is my orig array has negative number and they are way far away from 255. In Java this is the same case (meaning both the array in C# and Java have equivalent value) and the values is working fine in Java.

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

But I can't get that line translated into C#. Please help.

但我无法将该行翻译成 C#。请帮忙。

回答by mackenir

You can use Bitmap.LockBitsto obtain the bitmap data that you can then manipulate directly, rather than via SetPixel. (How to use LockBits)

您可以使用Bitmap.LockBits来获取位图数据,然后您可以直接操作这些数据,而不是通过 SetPixel。(如何使用 LockBits)

回答by Marc Gravell

Well, I'm assuming each int is the composite ARGB value? If there isn't an easy option, then LockBitsmight be worth looking at - it'll be a lot quicker than SetPixel, but is more complex. You'll also have to make sure you know how the int is composed (ARGB? RGBA?). I'll try to see if there is a more obvious option...

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

回答by Frank Krueger

Using WPF, you can create a bitmap (image) directly from your array. You can then encode this image or display it or play with it:

使用 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);

回答by user21826

I would recommend using LockBits but a slower SetPixel based algorithm might look something like

我建议使用 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;
}

回答by tafa

MemoryImageSource's constructor's 3rd argument is an array of ints composed of argb values in that order

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

The example in that page creates such an array by;

该页面中的示例通过以下方式创建了这样一个数组;

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

You need to decompose that integer array to a byte array (shift operator would be useful), but it should be in bgr order, for LockBits method to work.

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

回答by Marc Gravell

I like the WPF option already presented, but here it is using LockBitsand Bitmap:

我喜欢已经提供的 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);

With (as test data):

与(作为测试数据):

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