Несколько указателей на другие массивы из одного растрового изображения - PullRequest
0 голосов
/ 20 октября 2019

У меня есть метод для копирования Bitmap в массив byte с использованием Marshal.Copy:

    public byte[][] PrepareTestSamples(Bitmap bitmap, int imageCount, out BitmapData bitmapData)
    {
        bitmapData = bitmap.LockBits(
            new Rectangle(0, 0, bitmap.Width, bitmap.Height),
            ImageLockMode.ReadWrite,
            bitmap.PixelFormat);

        int pixelsCount = bitmapData.Stride * bitmap.Height;
        byte[][] images = new byte[imageCount * 3][];

        for (int i = 0; i < imageCount * 3; i++)
        {
            images[i] = new byte[pixelsCount];
            Marshal.Copy(bitmapData.Scan0, images[i], 0, pixelsCount);
        }

        return images;
    }

И этот код работает отлично. Я могу скопировать изображение в байтовые массивы imageCount * 3 раз.

Затем я использую эти массивы для проверки моих алгоритмов. Определение любого алгоритма выглядит следующим образом:

    byte[] Execute(byte[] pixels, int stride, int height, int width);

После выполнения алгоритма я возвращаю новый byte[] с измененными пикселями. Затем я снова копирую его в новый Bitmap, используя Lockbits.

var bmp = new Bitmap(bitmap.Width, bitmap.Height);
BitmapData bmpData = bmp.LockBits(
           new Rectangle(0, 0, bmp.Width, bmp.Height),
           ImageLockMode.ReadWrite,
           bitmap.PixelFormat);

        Marshal.Copy(images[1], 0, bmpData.Scan0, images[1].Length);
        bmp.UnlockBits(bmpData);

Я хочу протестировать свою программу, используя pointers. Я хочу проверить это, если указатели в этом случае будут быстрее, чем управляемая память.

Я думаю, что определение любого алгоритма должно быть изменено на:

byte[] Execute(byte* pixels, int stride, int height, int width);

Но у меня есть вопрос, как скопировать BitmapData в нечто вроде массива указателей? Как сохранить imagesCount * 3 изображения в виде указателей и передать pointer методу один за другим?

1 Ответ

1 голос
/ 20 октября 2019

Ваш код будет выглядеть примерно так

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
    class Program
    {
        public struct BitmapData
        {
            public int stride { get; set; }
            public int height { get; set; }
            public int width { get; set; }
            public long length { get; set; }
            public byte[] pixels { get; set; } 
        }
        public class ManagedBitmapData
        {
            public int stride { get; set; }
            public int height { get; set; }
            public int width { get; set; }
            public long length { get; set; }
            public byte[] pixels { get; set; }
        }

        static void Main(string[] args)
        {
            //source data
            List<ManagedBitmapData> managedData = new List<ManagedBitmapData>();
            IntPtr[] UnmanagedData = new IntPtr[managedData.Count];
            BitmapData[] bitMaps = new BitmapData[managedData.Count];
            for (int i = 0; i < managedData.Count; i++)
            {
                bitMaps[i] = new BitmapData();
                bitMaps[i].stride = managedData[i].stride;
                bitMaps[i].height = managedData[i].height;
                bitMaps[i].width = managedData[i].width;
                bitMaps[i].length = managedData[i].length;
                bitMaps[i].pixels = managedData[i].pixels;
                Marshal.StructureToPtr(bitMaps[i], UnmanagedData[i], true);
            }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...