2016-12-20 3 views
2

SoftwareBitmap является новым в UWP. Я начинаю с этого:Как изменить размер SoftwareBitmap?

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? 

Я в затруднении. Спасибо.

Обратите внимание: я не имею в виду BitmapImage; Я имею в виду SoftwareBitmap.

+0

Это может быть любой язык. Изменение размера изображений не просто. Здесь есть несколько алгоритмов на языке C: https://github.com/MalcolmMcLean/babyxrc/tree/master/src –

+0

Я использовал ImageMagick для этого в прошлом. Это было довольно просто https://magick.codeplex.com/ –

+0

Возможно, посмотрите на методы ScaledHeight и ScaledWidth на BitmapTransform? https://msdn.microsoft.com/library/windows/apps/br226254#methods Не моя область, а просто Google-догадка. – JohnLBevan

ответ

2

Похоже на костыль, но это может решить вашу проблему:

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; 
    } 

Вы должны получить пакет Win2D от NuGet.

2

Я сделал несколько попыток с ScaleEffect и закончил с помощью метода расширения ниже. На самом деле метод требует больше работы над этим, но, возможно, это поможет вам как-то продвинуться дальше.

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); 
    } 
} 
1

Здесь я взять файл изображения и уменьшить его до 100х100 SoftwareBitmap и вернуть его в качестве ImageSource.

Поскольку у вас уже есть SoftwareBitmap, я думаю, что ваша задача будет еще проще. Но надеюсь, что это даст вам представление.

Нам понадобится WritableBitmap только для его PixelBuffer при инициализации нашего недавно измененного экземпляра SoftwareBitmap. Если вы можете напрямую создать IBuffer из байт [] пиксельных данных, у нас есть (пикселей локальная переменная), вы можете напрямую предоставить его методу SoftwareBitmap.CreateCopyFromBuffer(). В этом случае нет необходимости в WritableBitmap.

Вот код:

private async Task<ImageSource> ProcessImageAsync(StorageFile ImageFile) 
    { 
     if (ImageFile == null) 
      throw new ArgumentNullException("ImageFile cannot be null."); 

     //The new size of processed image. 
     const int side = 100; 

     //Initialize bitmap transformations to be applied to the image. 
     var transform = new BitmapTransform() { ScaledWidth = side, ScaledHeight = side, InterpolationMode = BitmapInterpolationMode.Cubic }; 

     //Get image pixels. 
     var stream = await ImageFile.OpenStreamForReadAsync(); 
     var decoder = await BitmapDecoder.CreateAsync(stream.AsRandomAccessStream()); 
     var pixelData = await decoder.GetPixelDataAsync(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied, transform, ExifOrientationMode.RespectExifOrientation, ColorManagementMode.ColorManageToSRgb); 
     var pixels = pixelData.DetachPixelData(); 

     //Initialize writable bitmap. 
     var wBitmap = new WriteableBitmap((int)decoder.PixelWidth, (int)decoder.PixelHeight); 
     await wBitmap.SetSourceAsync(stream.AsRandomAccessStream()); 

     //Create a software bitmap from the writable bitmap's pixel buffer. 
     var sBitmap = SoftwareBitmap.CreateCopyFromBuffer(wBitmap.PixelBuffer, BitmapPixelFormat.Bgra8, side, side, BitmapAlphaMode.Premultiplied); 

     //Create software bitmap source. 
     var sBitmapSource = new SoftwareBitmapSource(); 
     await sBitmapSource.SetBitmapAsync(sBitmap); 

     return sBitmapSource; 
    } 

PS. Я знаю, что это предложение не должно быть частью ответа, но я должен сказать, что я многому научился о XAML/C# и разработке приложений Windows Store из ваших видео MVA и Channel9! :)

+0

Это дорого? –

+0

Не так много, но позже я понял, что это можно сделать очень прямолинейно. Я задал еще один вопрос об изменении размера и оттенках серого в SoftwareBitmap. Посмотрите на это (https://stackoverflow.com/a/45393902/4062881), это лучше, чем у меня, с точки зрения производительности. –

+0

@ JerryNixon-MSFT Вы также можете использовать Lumia Imaging SDK - https://msdn.microsoft.com/en-us/library/mt598502.aspx. Это здорово! –