17

I'm trying to get the pixel data from a WPF BitmapSource object. As I understand, this can be accomplished by calling its CopyPixels method. This method needs a stride parameter, which I don't know how to obtain. As far as I know, stride is value that's used when stepping in the array during reading or copying. What would be an appropriate stride value for any BitmapSource?

Tamás Szelei
  • 23,169
  • 18
  • 105
  • 180

2 Answers2

23

You can use stride = pixel_size * image_width value. For example, for RGBA bitmap with 100 pixel width, stride = 400.

Some applications may require special line alignment. For example, Windows GDI bitmaps require 32-bits line alignment. In this case, for RGB bitmap with width = 33, stride value 33*3=99 should be changed to 100, to have 32-bits line alignment in destination array.

Generally, you should know destination array requirements. In there are no special requirements, use default pixel_size * image_width.

Alex F
  • 42,307
  • 41
  • 144
  • 212
  • 2
    So I guess it's pixel size in bytes then? – Tamás Szelei Oct 07 '10 at 14:15
  • 7
    Yes, this is pixel size in bytes. BitmapSource.Format property returns PixelFormat structure. For example, pixel size for Bgr32 is 4, for Bgr24 - 3, for Gray8 - 1 etc. Copying bitmap data to array, you need to know exactly resulting array structure, and it is defined by Format property. – Alex F Oct 07 '10 at 14:43
  • 1
    I personnally use code like this to have 32-bit alignment (so that I can create a System.Drawing.Bitmap from the wpf image) : `var stride = width * (bitmapSource.Format.BitsPerPixel / 8); stride += (4 - stride % 4);` – odalet Apr 05 '13 at 16:39
  • Oups, there is a bug above. If the width is already 32-bit aligned, I add an extra 4 bytes to the stride... so the working code should be `var stride = width * (bitmapSource.Format.BitsPerPixel / 8); var mod = stride % 4; if (mod != 0) stride += 4 - mod;` – odalet Apr 06 '13 at 10:15
  • 3
    @odalet - actually, your stride computation maybe ok with GDI+, but it's wrong with WPF BitmapSource. With BitmapSource.CopyPixels, you must not add the 32-bit padding. Alex's answer is correct, with WPF it's just PixelWidth*BitsPerPixel – Simon Mourier Jul 25 '14 at 13:53
  • Can stride = image.PixelWidth * (image.Format.BitsPerPixel + 7) / 8 be a good calculation in WPF? – Amir Mahdi Nassiri Apr 19 '18 at 07:23
3
var stride = ((bitmapSource.PixelWidth * bitmapSource.Format.BitsPerPixel + 31) / 32) * 4;

or

var stride = ((bitmapSource.PixelWidth * bitmapSource.Format.BitsPerPixel + 31) >> 5) << 2;
Andrey
  • 722
  • 2
  • 8
  • 17