10

MediaComposition を作成しようとしています。複数の png 画像を 1 つのビデオに結合することに成功しました。ただし、作成されたファイルの背景は黒です。最初は、ファイルが png ファイルだったからかもしれないと思ったのですが、jpg でも同じことが起こります。以下は、画像を保存する方法です。

public async Task<bool> Save(InkCanvas canvas, StorageFile file)
{

    if (canvas != null && canvas.InkPresenter.StrokeContainer.GetStrokes().Count > 0)
    {
        if (file != null)
        {
            using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.ReadWrite))
            {
                await canvas.InkPresenter.StrokeContainer.SaveAsync(stream);
            }
        }
        Clear(canvas);
        return true;
    }
    return false;
}

画像は問題なく保存されますが、背景はアルファです。これが意味することは、これらをチェーンしてメディア構成にしようとすると、背景がなく、黒としてレンダリングされるということです。これを修正するために MediaComposition を作成するときにオーバーレイを使用してみました:

MediaClip overlayVideoClip = MediaClip.CreateFromColor(Colors.White, new TimeSpan(0, 1, 0));
MediaOverlay mo = new MediaOverlay(overlayVideoClip);
MediaOverlayLayer mol = new MediaOverlayLayer();
mol.Overlays.Add(mo);

composition.OverlayLayers.Add(mol);

しかし、役に立たない。この場合、オーバーレイという用語の意味を誤解しているのではないかと疑っています。それで、私の質問は次のとおりです。構成時にビデオをオーバーレイすることは可能ですか?または、これを画像自体で行う必要がある場合、画像を背景付きで保存するにはどうすればよいですか?

編集:

これで進歩(?)しました。以下はコンパイルおよび実行されますが、真っ黒なイメージが作成されます。

    public async Task TestSave(InkCanvas canvas, StorageFile file)
    {
        RenderTargetBitmap rtb = 
           new RenderTargetBitmap();
        PixelFormats.Pbgra32);
        await rtb.RenderAsync(canvas);
        var pixelBuffer = await rtb.GetPixelsAsync();

        using (IRandomAccessStream stream = 
             await file.OpenAsync(FileAccessMode.ReadWrite))
        {                
            BitmapEncoder encoder = 
                 await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);

            encoder.SetPixelData(BitmapPixelFormat.Bgra8,
                BitmapAlphaMode.Straight,
                (uint)rtb.PixelWidth,
                (uint)rtb.PixelHeight,
                96d, 96d,
                pixelBuffer.ToArray());

            await encoder.FlushAsync();                
        }
    }

編集:

Win2Dライブラリを使用して問題を解決するこの回答を見つけました。それは私の実際の問題に対処するものではありませんが、それを回避できます。うまくいけば、そこにはより良い解決策があります。

4

1 に答える 1

5

これについて私が理解している唯一のことは、背景付きの画像を保存しようとしているということです。これを解決するための私の提案は、あなたが持っている透明な画像を次のようなものに保存することです

<StackPanel x:Name="AreaWhichWillBeSavedToImage" Background=*Some Color*>
  <Image x:Name="theAlphaImage">
</StackPanel>

画像を GUI に表示したくない場合は、非表示に設定してください。

次に、選択した色の背景でファイルを保存できます。

var bitmap = await SaveToFileAsync(AreaWhichWillBeSavedToImage, await StorageFile.GetFileFromPathAsync(Windows.ApplicationModel.Package.Current.InstalledLocation.Path + @"someimage.jpg"));

  async Task<RenderTargetBitmap> SaveToFileAsync(FrameworkElement uielement, StorageFile file)
    {
        if (file != null)
        {
            CachedFileManager.DeferUpdates(file);

            Guid encoderId = GetBitmapEncoder(file.FileType);

            try
            {
                using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
                {
                    return await CaptureToStreamAsync(uielement, stream, encoderId);
                }
            }
            catch (Exception ex)
            {
                //DisplayMessage(ex.Message);
            }

            var status = await CachedFileManager.CompleteUpdatesAsync(file);
        }

        return null;
    }

    async Task<RenderTargetBitmap> CaptureToStreamAsync(FrameworkElement uielement, IRandomAccessStream stream, Guid encoderId)
    {
        try
        {
            var renderTargetBitmap = new RenderTargetBitmap();
            await renderTargetBitmap.RenderAsync(uielement);

            var pixels = await renderTargetBitmap.GetPixelsAsync();

            var logicalDpi = DisplayInformation.GetForCurrentView().LogicalDpi;
            var encoder = await BitmapEncoder.CreateAsync(encoderId, stream);
            encoder.SetPixelData(
                BitmapPixelFormat.Bgra8,
                BitmapAlphaMode.Ignore,
                (uint)renderTargetBitmap.PixelWidth,
                (uint)renderTargetBitmap.PixelHeight,
                logicalDpi,
                logicalDpi,
                pixels.ToArray());

            await encoder.FlushAsync();

            return renderTargetBitmap;
        }
        catch (Exception ex)
        {
            //DisplayMessage(ex.Message);
        }

        return null;
    }

    Guid GetBitmapEncoder(string fileType)
    {
        Guid encoderId = BitmapEncoder.JpegEncoderId;
        switch (fileType)
        {
            case ".bmp":
                encoderId = BitmapEncoder.BmpEncoderId;
                break;
            case ".gif":
                encoderId = BitmapEncoder.GifEncoderId;
                break;
            case ".png":
                encoderId = BitmapEncoder.PngEncoderId;
                break;
            case ".tif":
                encoderId = BitmapEncoder.TiffEncoderId;
                break;
        }

        return encoderId;
    }
于 2015-12-01T18:05:24.773 に答える