See the question and my original answer on StackOverflow

You have an IntPtr on one side and a Stream on the other side, so you need a Stream implementation over an IntPtr.

You can do this using the UnmanagedMemoryStream Class and a custom SafeBuffer class:

public sealed class IntPtrBuffer : SafeBuffer
{
    public IntPtrBuffer(IntPtr pointer, long byteLength)
        : base(false)
    {
        handle = pointer;
        Initialize((ulong)byteLength);
    }

    protected override bool ReleaseHandle() => true;
}

and use it like this:

var bitmap = new Bitmap("image.png");

var imageBitmap = new WriteableBitmap(bitmap.Width, bitmap.Height);

var bitmapData = bitmap.LockBits(
    new Rectangle(0, 0, bitmap.Width, bitmap.Height),
    ImageLockMode.ReadOnly, bitmap.PixelFormat
);

var byteLength = bitmapData.Height * bitmapData.Stride;
using var ums = new UnmanagedMemoryStream(new IntPtrBuffer(bitmapData.Scan0, byteLength), 0, byteLength);
using var pixels = imageBitmap.PixelBuffer.AsStream();
ums.CopyTo(pixels);

bitmap.UnlockBits(bitmapData);

this.image.Source = imageBitmap;