Pregunta

Estoy intentando conseguir un mapa de bits creado a partir de los datos en bruto para mostrar en WPF, mediante el uso de una imagen y un BitmapSource:

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

for (Int32 i = 0; i < RenderHeight; i++)
{
    for (Int32 j = 0; j < RenderWidth; j++)
    {
        Int32 index = j + (i * RenderHeight);

        if (i + j % 2 == 0)
            data[index] = 0xFF0000;
        else
            data[index] = 0x00FF00;
    }
}

BitmapSource source = BitmapSource.Create(RenderWidth, RenderHeight, 96.0, 96.0, PixelFormats.Bgr32, null, data, 0);

RenderImage.Source = source;

Sin embargo, la llamada a BitmapSource.Create lanza una excepción ArgumentException, diciendo "Valor no está dentro del rango esperado". No es esta la manera de hacer esto? ¿No estoy haciendo esa llamada correctamente?

¿Fue útil?

Solución

Su zancada es incorrecta. Zancada es el número de bytes asignada a una línea de barrido de la mapa de bits. Por lo tanto, utilizar lo siguiente:

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

y sustituir el último parámetro (actualmente 0) con stride como se definió anteriormente.

Aquí es una explicación para la misteriosa fórmula zancada:

Hecho: Scanlines deben estar alineados en límites de 32 bits ( referencia ) .

La fórmula naive para el número de bytes por línea de exploración sería:

(width * bpp) / 8

Pero esto podría no nos dan un mapa de bits alineados en un límite de 32 bits y (ancho * bpp) podría ni siquiera han sido divisible por 8.

Por lo tanto, lo que hacemos es forzar nuestro mapa de bits para tener al menos 32 bits en una fila (suponemos que width > 0):

width * bpp + 31

y luego decimos que no se preocupan por los bits de orden inferior (bits 0--4), porque estamos tratando de alinear en límites de 32 bits:

(width * bpp + 31) & ~31

y luego se divide por 8 para volver a bytes:

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

El relleno puede ser calculado por

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

La fórmula ingenuo sería

stride - ((width * bpp) / 8)

Pero width * bpp podría no alinearse en un límite de byte y cuando no lo hace esta fórmula sería contar sobre el relleno de un byte. (Piense en un 1 píxel de ancho de mapa de bits 1 BPP. El paso es 4 y la fórmula ingenua diría que el relleno es 4, pero en realidad es 3.) Por lo tanto añadiremos un poco para cubrir el caso de que no es un width * bpp byte límite y entonces obtenemos la fórmula correcta dado anteriormente.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top