Converting an array of Pixels to an image in C#

前端 未结 6 1510
孤城傲影
孤城傲影 2020-12-28 11:20

I have an array of int pixels 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 equiva

相关标签:
6条回答
  • 2020-12-28 11:40

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

    0 讨论(0)
  • 2020-12-28 11:40

    Well, I'm assuming each int is the composite ARGB value? If there isn't an easy option, then LockBits might 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...

    0 讨论(0)
  • 2020-12-28 11:48

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

    
    // 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;
    }
    
    0 讨论(0)
  • 2020-12-28 11:53

    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:

    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);
    
    0 讨论(0)
  • 2020-12-28 11:53

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

    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.

    0 讨论(0)
  • 2020-12-28 11:57

    I like the WPF option already presented, but here it is using LockBits and 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);
    

    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;
        }
    
    0 讨论(0)
提交回复
热议问题