michasaucer
michasaucer

Reputation: 5236

Multiple pointers to another arrays from one Bitmap

I have a method to copying Bitmap to array of byte using 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;
    }

And this code works perfectly. I can copy image to byte arrays imageCount * 3 times.

Then im using this arrays to test my algorithms. The definition of any algorithm looks like this:

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

After executing algorithm im returning new byte[] with changed pixels. Then i copying it back to new Bitmap again using 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);

I want to test my program using pointers. I want to check it, if pointers in this case will be faster than managed memory.

I think, that definition of any algorithm must be changed to:

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

But i have question, how to copy BitmapData to something like array of pointers? How to store imagesCount * 3 images as pointers and pass pointer to method one by one?

Upvotes: 0

Views: 28

Answers (1)

jdweng
jdweng

Reputation: 34429

Your code would look something like this

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

Upvotes: 1

Related Questions