Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to resize a SoftwareBitmap?

Tags:

c#

uwp

SoftwareBitmap is new in UWP. I start with this:

var softwareBitmap = EXTERNALVALUE;

// do I even need a writeable bitmap?
var writeableBitmap = new WriteableBitmap(softwareBitmap.PixelWidth, softwareBitmap.PixelHeight);
softwareBitmap.CopyToBuffer(writeableBitmap.PixelBuffer);

// maybe use BitmapDecoder?

I am at a loss. Thank you.

Please note, I don't mean BitmapImage; I mean SoftwareBitmap.

like image 449
Jerry Nixon Avatar asked Oct 27 '25 02:10

Jerry Nixon


2 Answers

I've made some tries with ScaleEffect and ended with extension method below. In fact the method needs more work on it, but maybe it will help you somehow to move further.

public static SoftwareBitmap Resize(this SoftwareBitmap softwareBitmap, float newWidth, float newHeight)
{
    using (var resourceCreator = CanvasDevice.GetSharedDevice())
    using (var canvasBitmap = CanvasBitmap.CreateFromSoftwareBitmap(resourceCreator, softwareBitmap))
    using (var canvasRenderTarget = new CanvasRenderTarget(resourceCreator, newWidth, newHeight, canvasBitmap.Dpi))
    using (var drawingSession = canvasRenderTarget.CreateDrawingSession())
    using (var scaleEffect = new ScaleEffect())
    {
        scaleEffect.Source = canvasBitmap;
        scaleEffect.Scale = new System.Numerics.Vector2(newWidth / softwareBitmap.PixelWidth, newHeight / softwareBitmap.PixelHeight);
        drawingSession.DrawImage(scaleEffect);
        drawingSession.Flush();
        return SoftwareBitmap.CreateCopyFromBuffer(canvasRenderTarget.GetPixelBytes().AsBuffer(), BitmapPixelFormat.Bgra8, (int)newWidth, (int)newHeight, BitmapAlphaMode.Premultiplied);
    }
}
like image 183
Romasz Avatar answered Oct 28 '25 15:10

Romasz


Looks like a crutch but it might resolve your problem:

    private async Task<SoftwareBitmap> ResizeSoftwareBitmap(SoftwareBitmap softwareBitmap, double scaleFactor)
    {
        var resourceCreator = CanvasDevice.GetSharedDevice();
        var canvasBitmap = CanvasBitmap.CreateFromSoftwareBitmap(resourceCreator, softwareBitmap);
        var canvasRenderTarget = new CanvasRenderTarget(resourceCreator, (int)(softwareBitmap.PixelWidth * scaleFactor), (int)(softwareBitmap.PixelHeight * scaleFactor), 96);

        using (var cds = canvasRenderTarget.CreateDrawingSession())
        {
            cds.DrawImage(canvasBitmap, canvasRenderTarget.Bounds);
        }

        var pixelBytes = canvasRenderTarget.GetPixelBytes();

        var writeableBitmap = new WriteableBitmap((int)(softwareBitmap.PixelWidth * scaleFactor), (int)(softwareBitmap.PixelHeight * scaleFactor));
        using (var stream = writeableBitmap.PixelBuffer.AsStream())
        {
            await stream.WriteAsync(pixelBytes, 0, pixelBytes.Length);
        }

        var scaledSoftwareBitmap = new SoftwareBitmap(BitmapPixelFormat.Bgra8, (int)(softwareBitmap.PixelWidth * scaleFactor), (int)(softwareBitmap.PixelHeight * scaleFactor));
        scaledSoftwareBitmap.CopyFromBuffer(writeableBitmap.PixelBuffer);

        return scaledSoftwareBitmap;
    }

You have to get Win2D package from nuget.

like image 30
Jet Chopper Avatar answered Oct 28 '25 15:10

Jet Chopper