Pergunta

Estou tentando criar um bitmap a partir de dados brutos para mostrar no WPF, usando uma imagem e um 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;

No entanto, a chamada para o bitmapsource.create lança uma argumentação, dizendo "o valor não se enquadra no intervalo esperado". Não é essa a maneira de fazer isso? Não estou fazendo essa chamada corretamente?

Foi útil?

Solução

Seu passo está incorreto. STRIDE é o número de bytes alocados para uma linha de varredura do bitmap. Assim, use o seguinte:

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

e substitua o último parâmetro (atualmente 0) com stride conforme definido acima.

Aqui está uma explicação para a fórmula misteriosa do passo:

Fato: as linhas de varredura devem estar alinhadas em limites de 32 bits (referência).

A fórmula ingênua para o número de bytes por scanline seria:

(width * bpp) / 8

Mas isso pode não nos dar um bitmap alinhado em um limite de 32 bits e (largura * bpp) pode nem ter sido divisível por 8.

Então, o que fazemos é forçar nosso bitmap a ter pelo menos 32 bits seguidos (assumimos que width > 0):

width * bpp + 31

E então dizemos que não nos importamos com os bits de ordem baixa (bits 0--4) porque estamos tentando alinhar-se nos limites de 32 bits:

(width * bpp + 31) & ~31

e depois divida por 8 para voltar aos bytes:

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

O preenchimento pode ser calculado por

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

A fórmula ingênua seria

stride - ((width * bpp) / 8)

Mas width * bpp pode não se alinhar em um limite de byte e, quando não, essa fórmula contaria demais o preenchimento por um byte. (Pense em um bitmap largo de 1 pixels usando 1 bpp. O passo é 4 e a fórmula ingênua diria que o preenchimento é 4, mas na realidade é 3.) Por isso, adicionamos um pouco para cobrir o caso que width * bpp não é um limite de byte e, em seguida, obtemos a fórmula correta dada acima.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top