Domanda

Sto cercando di ottenere una bitmap creata da dati grezzi da mostrare in WPF, utilizzando un'immagine e 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;

Tuttavia, la chiamata a BitmapSource.Create genera un'ArgumentException, dicendo che "Il valore non rientra nell'intervallo previsto".Non è questo il modo per farlo?Non sto effettuando quella chiamata correttamente?

È stato utile?

Soluzione

Il tuo passo non è corretto.Stride è il numero di byte assegnati per una linea di scansione della bitmap.Pertanto, utilizzare quanto segue:

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

e sostituire l'ultimo parametro (attualmente 0) con stride come sopra definito.

Ecco una spiegazione per la misteriosa formula del passo:

Fatto:Le linee di scansione devono essere allineate sui limiti a 32 bit (riferimento).

La formula ingenua per il numero di byte per linea di scansione sarebbe:

(width * bpp) / 8

Ma questo potrebbe non darci una bitmap allineata su un limite di 32 bit e (larghezza * bpp) potrebbe non essere nemmeno divisibile per 8.

Quindi, quello che facciamo è forzare la nostra bitmap ad avere almeno 32 bit di fila (supponiamo che width > 0):

width * bpp + 31

e poi diciamo che non ci interessano i bit di ordine inferiore (bit 0--4) perché stiamo cercando di allinearci sui limiti di 32 bit:

(width * bpp + 31) & ~31

e poi dividere per 8 per tornare ai byte:

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

L'imbottitura può essere calcolata da

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

La formula ingenua sarebbe

stride - ((width * bpp) / 8)

Ma width * bpp potrebbe non allinearsi su un limite di byte e in caso contrario questa formula conterebbe eccessivamente il riempimento di un byte.(Pensa a una bitmap larga 1 pixel che utilizza 1 bpp.Il passo è 4 e la formula ingenua direbbe che il riempimento è 4 ma in realtà è 3.) Quindi aggiungiamo un po' per coprire il caso che width * bpp non è un limite di byte e quindi otteniamo la formula corretta indicata sopra.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top