2015-11-23 14 views
10

Próbuję utworzyć MediaComposition. Udało mi się połączyć wiele obrazów png w jeden film; jednak utworzone pliki mają czarne tło. Początkowo myślałem, że może to być spowodowane tym, że pliki były plikami png, ale samo zachowanie dotyczy jpgs. Oto, w jaki sposób zapisuję obraz:Dodaj kolor tła do MediaComposition

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

Zapisuje obraz w porządku, ale tło to alfa. Oznacza to, że gdy próbuję połączyć je w kompozycję medialną, nie ma tła, a jest ono czarne. Próbowałem użyć nakładek podczas tworzenia MediaComposition, aby to poprawić:

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

Ale na próżno. Podejrzewam, że w tym przypadku nie rozumiem znaczenia terminu "nakładka". Moje pytania brzmią: czy można nakładać wideo w czasie kompozycji, a jeśli tak, to w jaki sposób? Ewentualnie, jeśli trzeba to zrobić na obrazie, w jaki sposób mogę zapisać obraz z tłem?

EDYTOWANIE:

Zrobiłem postęp (?) Z tym; następujące kompiluje i działa, ale tworzy solidną czarny obraz:

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

EDIT:

znalazłem this odpowiedź, która rodzaju rozwiązuje problem przy użyciu biblioteki Win2D; chociaż nie rozwiązuje mojego prawdziwego problemu, pozwala mi to obejść. Mam nadzieję, że istnieje lepsze rozwiązanie.

+0

Nie wiadomo, co próbujesz zrobić. Po prostu zapisz obraz bez tła alfa? –

+0

Zapisz obraz z tłem lub ułóż tło w momencie tworzenia pliku wideo (obecnie korzystasz z MediaComposition). –

Odpowiedz

5

Jedyne, co rozumiem, to próba zapisania obrazu z tłem. Moja sugestia, aby rozwiązać ten jest aby zapisać przezroczysty obraz trzeba coś jak

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

Teraz, jeśli nie chcemy, aby wyświetlić obraz na GUI po prostu ustawić go na Ukryty.

Następnie można zapisać plik z wybranym kolorem tła.

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

Nie wydaje mi się, żeby to działało dla InkCanvas –

+0

Zapisz obraz InkCanvas jako ImageSourceAlphaImage, to działa –

+0

Jeśli masz na myśli to: wtedy to nie działa –