HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Faster copying of images to change their PixelFormat

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
pixelformatfastercopyingimageschangetheir

Problem

I have the following code below that creates a new Bitmap object the same as the original but to ensure that its PixelFormat is 24bppRgb. Does anyone know if there is a faster way to do this:

using (Bitmap bitmap = new Bitmap(image.Width, image.Height, PixelFormat.Format24bppRgb))
{
    using (Graphics g = Graphics.FromImage(bitmap))
    {
        g.DrawImage(image, new Rectangle(0, 0, bitmap.Width, bitmap.Height));
    }

    //...

Solution

To remove the alpha channel, you could use Bitmap.Clone :

public static Bitmap RemoveAlphaChannel(Bitmap bitmap) {
    var rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
    return bitmap.Clone(rect, PixelFormat.Format24bppRgb);
}


Another way is to lock the bits without the alpha channel and then copy the memory to a new bitmap:

public static Bitmap RemoveAlphaChannel(Bitmap bitmap) {
    Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
    Bitmap bitmapDest = (Bitmap)new Bitmap(bitmap.Width, bitmap.Height, PixelFormat.Format24bppRgb);
    BitmapData data = bitmap.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
    BitmapData dataDest = bitmapDest.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
    NativeMethods.CopyMemory(dataDest.Scan0, data.Scan0, (uint)data.Stride * (uint)data.Height);
    bitmap.UnlockBits(data);
    bitmapDest.UnlockBits(dataDest);
    return bitmapDest;
}

static class NativeMethods {

    const string KERNEL32 = "Kernel32.dll";

    [DllImport(KERNEL32)]
    public extern static void CopyMemory(IntPtr dest, IntPtr src, uint length);

}

Code Snippets

public static Bitmap RemoveAlphaChannel(Bitmap bitmap) {
    var rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
    return bitmap.Clone(rect, PixelFormat.Format24bppRgb);
}
public static Bitmap RemoveAlphaChannel(Bitmap bitmap) {
    Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
    Bitmap bitmapDest = (Bitmap)new Bitmap(bitmap.Width, bitmap.Height, PixelFormat.Format24bppRgb);
    BitmapData data = bitmap.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
    BitmapData dataDest = bitmapDest.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
    NativeMethods.CopyMemory(dataDest.Scan0, data.Scan0, (uint)data.Stride * (uint)data.Height);
    bitmap.UnlockBits(data);
    bitmapDest.UnlockBits(dataDest);
    return bitmapDest;
}

static class NativeMethods {

    const string KERNEL32 = "Kernel32.dll";

    [DllImport(KERNEL32)]
    public extern static void CopyMemory(IntPtr dest, IntPtr src, uint length);

}

Context

StackExchange Code Review Q#127064, answer score: 5

Revisions (0)

No revisions yet.