Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why must "stride" in the System.Drawing.Bitmap constructor be a multiple of 4?

I am writing an application that requires me to take a proprietary bitmap format (an MVTec Halcon HImage) and convert it into a System.Drawing.Bitmap in C#.

The only proprietary functions given to me to help me do this involve me writing to file, except for the use of a "get pointer" function.

This function is great, it gives me a pointer to the pixel data, the width, the height, and the type of the image.

My issue is that when I create my System.Drawing.Bitmap using the constructor:

new System.Drawing.Bitmap(width, height, stride, format, scan) 

I need to specify a "stride" that is a multiple of 4. This may be a problem as I am unsure what size bitmap my function will be hit with. Supposing I end up with a bitmap that is 111x111 pixels, I have no way to run this function other than adding a bogus column to my image or subtracting 3 columns.

Is there a way I can sneak around this limitation?

like image 445
Gorchestopher H Avatar asked Feb 02 '10 16:02

Gorchestopher H


People also ask

What is bitmap stride?

The stride is the width of a single row of pixels (a scan line), rounded up to a four-byte boundary. If the stride is positive, the bitmap is top-down. If the stride is negative, the bitmap is bottom-up.

What is System drawing bitmap?

Encapsulates a GDI+ bitmap, which consists of the pixel data for a graphics image and its attributes. A Bitmap is an object used to work with images defined by pixel data.

What is the use of new bitmap image?

Bitmap (BMP) is an image file format that can be used to create and store computer graphics. A bitmap file displays a small dots in a pattern that, when viewed from afar, creates an overall image.


1 Answers

This goes back to early CPU designs. The fastest way to crunch through the bits of the bitmap is by reading them 32-bits at a time, starting at the start of a scan line. That works best when the first byte of the scan line is aligned on a 32-bit address boundary. In other words, an address that's a multiple of 4. On early CPUs, having that first byte mis-aligned would cost extra CPU cycles to read two 32-bit words from RAM and shuffle the bytes to create the 32-bit value. Ensuring each scan line starts at an aligned address (automatic if the stride is a multiple of 4) avoids that.

This isn't a real concern anymore on modern CPUs, now alignment to the cache line boundary is much more important. Nevertheless, the multiple of 4 requirement for stride stuck around for appcompat reasons.

Btw, you can easily calculate the stride from the format and width with this:

        int bitsPerPixel = ((int)format & 0xff00) >> 8;         int bytesPerPixel = (bitsPerPixel + 7) / 8;         int stride = 4 * ((width * bytesPerPixel + 3) / 4); 
like image 50
Hans Passant Avatar answered Sep 21 '22 11:09

Hans Passant