2016-12-20 153 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

BitmapTransformのScaledHeightとScaledWidthメソッドを見たことがありますか? 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; 
    } 

あなたはnugetからWin2Dパッケージを取得する必要があります。

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#について多くのことを学び、あなたのMVAやChannel9ビデオからWindows Storeアプリケーションを開発していると言わなければなりません! :)

+0

これは高価ですか? –

+0

それほど多くはありませんが、私は後でこれがずっと真っ直ぐ前進していることに気付きました。 SoftwareBitmapのサイズ変更とグレースケールに関する別の質問をしました。これを見てみると(https://stackoverflow.com/a/45393902/4062881)、それは私よりもパフォーマンスが優れています。 –

+0

@ JerryNixon-MSFT Lumia Imaging SDK(https://msdn.microsoft.com/en-us/library/mt598502.aspx)を使用することもできます。それは素晴らしいです! –

関連する問題