c# - studio - uwp vs wpf
Agregue un color de fondo a una MediaComposition (1)
Lo único que entiendo acerca de esto es que estás tratando de guardar una imagen con un fondo. Mi sugerencia para resolver esto es guardar la imagen transparente que tiene a algo así como
<StackPanel x:Name="AreaWhichWillBeSavedToImage" Background=*Some Color*>
<Image x:Name="theAlphaImage">
</StackPanel>
Ahora, si no desea que la imagen se muestre en su GUI, simplemente configúrelo en Oculto.
Luego puede guardar el archivo con el fondo de color de su elección.
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;
}
Estoy tratando de crear una MediaComposition. He logrado combinar múltiples imágenes png en un solo video; sin embargo, los archivos que se crean tienen un fondo negro. Al principio, pensé que esto podría deberse a que los archivos eran archivos png, pero el mismo comportamiento se produce para jpgs. A continuación se muestra cómo estoy guardando la imagen:
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;
}
Guarda bien la imagen, pero el fondo es alfa. Lo que esto significa es que cuando intento encadenarlos en una composición de medios, no hay fondo y se muestra como negro. He intentado usar superposiciones al crear la MediaComposition para corregir esto:
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);
Pero fue en vano. Mi sospecha es que estoy malinterpretando el significado del término superposición en este caso. Entonces, mis preguntas son: ¿es posible superponer el video en el momento de la composición y, de ser así, cómo? Alternativamente, si esto debe hacerse en la imagen en sí, ¿cómo puedo guardar la imagen con un fondo?
EDITAR:
He progresado (?) Con esto; las siguientes compilaciones y ejecuciones, pero crea una imagen negra sólida:
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();
}
}
EDITAR:
Encontré esta respuesta, que soluciona el problema usando la biblioteca de Win2D; aunque no aborda mi problema real, me permite dejarlo. Con suerte, hay una mejor solución por ahí.