Как получить новое растровое изображение из байтового массива с указателем IntPtr? - PullRequest
0 голосов
/ 13 ноября 2018

У меня проблема с методом Marshal.UnsafeAddrOfPinnedArrayElement().

То, что я хочу сделать, это вернуть Bitmap object из byte[] массива. Но сначала немного кода с пояснением того, что я делаю.

  1. Сначала я загружаю свой Bitmap в метод, который я возвращаю byte[] массив из него:

     //return tuple with pointer to array and byte[]array   
    public static (byte[], IntPtr) GetByteArray(Bitmap bitmap)
    {
    
        //lockbits 
        BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
                                                ImageLockMode.ReadWrite,
                                                bitmap.PixelFormat
                                                );
    
        int pixels = bitmapData.Stride * bitmap.Height;
        byte[] resultArray = new byte[pixels];
    
        //copying bytes to array
        Marshal.Copy(bitmapData.Scan0, resultArray, 0, pixels);
    
        bitmap.UnlockBits(bitmapData);
    
        //returns array and pointer to it
        return (resultArray, bitmapData.Scan0);
    }
    
  2. Во-вторых, я хочу отредактировать этот байтовый массив:

    public static Bitmap Execute(Bitmap bitmap, int[] filter)
    {
        //get byte array from method that i mentioned before with pointer to it
        (byte[] pixelsFromBitmap, IntPtr pointer) = PictureUtilities.GetByteArray(bitmap);
    
        byte[] newPixels = pixelsFromBitmap;
    
        int stride = bitmap.Width;
    
        int height = bitmap.Height;
        int width  = bitmap.Width;
    
        Parallel.For(0, height - 1, y =>
        {
            int offset = y * stride;
            for(int x = 0; x < width - 1; x++)
            {
                //some stuff i doing with array, not neceserry what im doing here
                int positionOfPixel = x + offset;
                newPixels[positionOfPixel] = (byte)122;
            }
    
        });
    
        //copying values from newPixels to pixelsFromBitmap that i get from method GetByteArray() that i mentioned it before
        newPixels.CopyTo(pixelsFromBitmap, 0);
    
        //copying bytes again
        Marshal.Copy(pixelsFromBitmap, 0, pointer, pixelsFromBitmap.Length);
    
        //generete new bitmap from byte array
        Bitmap result = new Bitmap(bitmap.Width, bitmap.Height, stride,
                                   bitmap.PixelFormat,
                                   pointer);
        return result;
    
    
    }
    

После всего этого процесса я получаю исключение в методе Execute(): System.ArgumentException в строке, когда я получаю новый Bitmap result.

Не могли бы вы сказать мне, что я делаю не так? я хочу получить байтовый массив из моего растрового изображения из метода (для удобства чтения), отредактировать его и вернуть новое растровое изображение в зависимости от моего нового байтового массива.

Могу поспорить, что я не совсем понял, как работает Marshall.Copy, и я ошибаюсь pointer в возвращении byte array из GetByteArray() метода.

Спасибо за помощь

...