Search code examples
c#wpfwriteablebitmap

Weirdness with WriteableBitmap in WPF


I'm creating a gray8 writeable bitmap in WPF/.Net 8.

When I set this to an Image Source, the result is a completely black image - of around the correct size.

If I save the writeable bitmap (using a PngEncoder), the image saves as I would expect. If I reload the png image from disk to the Image control then it displays perfectly fine.

However, If I recreate the image and resave it and reload it, it is not displayed - the original image is retained.

I'm mainly concerned about know what I need to do to make the writeable bitmap not appear black as I don't have a need to save and so on.

The intent of the bitmap is to show a series of bars whose darkness corresponds to the values in an array - a kind of density histogram

public BitmapSource CreateLineWeightImage()
{
    if (LineWeights == null) throw new InvalidOperationException("Must GetLineWeights first");

    WriteableBitmap lineWeights = new WriteableBitmap(LineWeightImageWidth, OriginalImage.PixelHeight, 96, 96, PixelFormats.Gray8, null);
    lineWeights.Lock();
    unsafe
    {
        for (int y = 0; y < lineWeights.PixelHeight; ++y)
        {
            for (int x = 0; x < LineWeightImageWidth; ++x)
            {
                byte* PixelPtr = (byte*)lineWeights.BackBuffer + y * lineWeights.BackBufferStride + x;

                *((byte*)PixelPtr) = (byte)LineWeights[y];
            }
        }
    }

    lineWeights.Unlock();
    LineWeightsImage = lineWeights;
    return lineWeights;
}

Thanks

Iain


Solution

  • You have to tell the WriteableBitmap which changes were made to its BackBuffer, by calling the AddDirtyRect method before Unlock:

    lineWeights.AddDirtyRect(new Int32Rect(
        0, 0, lineWeights.PixelWidth, lineWeights.PixelHeight));
    
    lineWeights.Unlock();