Why does BitmapSource.Create throw an ArgumentException?

后端 未结 1 1487
长情又很酷
长情又很酷 2020-12-03 09:00

I\'m trying to get an bitmap created from raw data to show in WPF, by using an Image and a BitmapSource:

Int32[] data = new Int32[RenderHeight * RenderWidth]         


        
相关标签:
1条回答
  • 2020-12-03 09:21

    Your stride is incorrect. Stride is the number of bytes allocated for one scanline of the bitmap. Thus, use the following:

    int stride = ((RenderWidth * 32 + 31) & ~31) / 8;
    

    and replace the last parameter (currently 0) with stride as defined above.

    Here is an explanation for the mysterious stride formula:

    Fact: Scanlines must be aligned on 32-bit boundaries (reference).

    The naive formula for the number of bytes per scanline would be:

    (width * bpp) / 8
    

    But this might not give us a bitmap aligned on a 32-bit boundary and (width * bpp) might not even have been divisible by 8.

    So, what we do is we force our bitmap to have at least 32 bits in a row (we assume that width > 0):

    width * bpp + 31
    

    and then we say that we don't care about the low-order bits (bits 0--4) because we are trying to align on 32-bit boundaries:

    (width * bpp + 31) & ~31
    

    and then divide by 8 to get back to bytes:

    ((width * bpp + 31) & ~31) / 8
    

    The padding can be computed by

    int padding = stride - (((width * bpp) + 7) / 8)
    

    The naive formula would be

    stride - ((width * bpp) / 8)
    

    But width * bpp might not align on a byte boundary and when it doesn't this formula would over count the padding by a byte. (Think of a 1 pixel wide bitmap using 1 bpp. The stride is 4 and the naive formula would say that the padding is 4 but in reality it is 3.) So we add a little bit to cover the case that width * bpp is not a byte boundary and then we get the correct formula given above.

    0 讨论(0)
提交回复
热议问题