如何将 CanvasControl 的内容添加到 MediaClip
How to add contents of CanvasControl to a MediaClip
我正在创建一个 uwp 应用程序,用户输入的文本会转换为视频叠加层。用户加载视频,输入文本,预览带有文本的视频,然后他们可以保存带有叠加层的视频。
现在它适用于图像叠加层,但不适用于文本。我正在尝试使用 win2d 来格式化文本。但是,我不知道如何将 win2d canvas 控件放入 windows.media.editing 媒体剪辑中。
我想我可以转到 CanvasControl > 某种位图 > 图像 > MediaClip,但媒体剪辑只能通过存储文件或直接 3d 表面创建。任何事情都会有帮助!这是我第一次尝试在游戏引擎之外写东西。
当前将canvas控件转换为位图的部分:
private async void btnAddOverlay_Click(object sender, RoutedEventArgs e)
{
var bitmap = new RenderTargetBitmap();
await bitmap.RenderAsync(canvasControl);
IBuffer pixelBuffer = await bitmap.GetPixelsAsync();
byte[] pixels = pixelBuffer.ToArray();
SoftwareBitmap outputBitmap = SoftwareBitmap.CreateCopyFromBuffer
(
pixelBuffer,
BitmapPixelFormat.Bgra8,
bitmap.PixelWidth,
bitmap.PixelHeight
);
}
将图像叠加到视频中的旧部分。 (overlayImageFile是存储文件,我只是不知道如何将outputBitmap转换成存储文件来制作媒体剪辑。)
private async void CreateOverlays()
{
// Create a clip from video and add it to the composition
var baseVideoClip = await MediaClip.CreateFromFileAsync(pickedFile);
composition = new MediaComposition();
composition.Clips.Add(baseVideoClip);
// Create a clip from image
var overlayImageClip = await MediaClip.CreateFromImageFileAsync(overlayImageFile,timeSpan);
// Put image in upper left corner, retain its native aspect ratio
Rect imageOverlayPosition;
imageOverlayPosition.Height = mediaElement.ActualHeight / 3;
imageOverlayPosition.Width = (double)imageBitmap.PixelWidth / (double)imageBitmap.PixelHeight * imageOverlayPosition.Height;
imageOverlayPosition.X = 0;
imageOverlayPosition.Y = 0;
// Make the clip from the image an overlay
var imageOverlay = new MediaOverlay(overlayImageClip);
imageOverlay.Position = imageOverlayPosition;
imageOverlay.Opacity = 0.8;
// Make a new overlay layer and add the overlay to it
var overlayLayer = new MediaOverlayLayer();
overlayLayer.Overlays.Add(imageOverlay);
composition.OverlayLayers.Add(overlayLayer);
//Render to MediaElement
mediaElement.Position = TimeSpan.Zero;
mediaStreamSource = composition.GeneratePreviewMediaStreamSource((int)mediaElement.ActualWidth, (int)mediaElement.ActualHeight);
mediaElement.SetMediaStreamSource(mediaStreamSource);
txbNotification.Text = "Overlay creaeted";
}
Windows 媒体剪辑 Class: https://docs.microsoft.com/en-us/uwp/api/windows.media.editing.mediaclip?view=winrt-19041
I just don't know how to convert outputBitmap to a storage file to make a media clip from it.
得到RenderTargetBitmap
后,不需要转换为SoftwareBitmap
。您可以通过BitmapEncoder
将像素数据存储为指定格式的文件。这是方法:
private async void btnAddOverlay_Click(object sender, RoutedEventArgs e)
{
RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
await renderTargetBitmap.RenderAsync(canvasControl);
var pixelBuffer = await renderTargetBitmap.GetPixelsAsync();
var pixels = pixelBuffer.ToArray();
var displayInformation = DisplayInformation.GetForCurrentView();
// Create the file in local folder
var file = await ApplicationData.Current.LocalFolder.CreateFileAsync("TempCanvas.png", CreationCollisionOption.ReplaceExisting);
// Write data
using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied, (uint)renderTargetBitmap.PixelWidth, (uint)renderTargetBitmap.PixelHeight, displayInformation.RawDpiX, displayInformation.RawDpiY, pixels);
await encoder.FlushAsync();
}
}
需要时,您可以使用以下代码获取保存的图片:
var file = await ApplicationData.Current.LocalFolder.GetFileAsync("TempCanvas.png");
这只是另一种可能的方式
如果您使用的是 win2d,则可以使用
MediaClip.CreateFromSurface(IDirect3DSurface, TimeSpan) 函数和
您可以将 canvas 渲染目标直接传递给此方法
这样您就不必将位图保存到文件
因此您必须创建离线 canvas 设备
然后是 canvas 渲染目标
然后在上面画文字
然后将该渲染目标传递给函数
它将生成用于叠加的媒体剪辑
我正在创建一个 uwp 应用程序,用户输入的文本会转换为视频叠加层。用户加载视频,输入文本,预览带有文本的视频,然后他们可以保存带有叠加层的视频。 现在它适用于图像叠加层,但不适用于文本。我正在尝试使用 win2d 来格式化文本。但是,我不知道如何将 win2d canvas 控件放入 windows.media.editing 媒体剪辑中。
我想我可以转到 CanvasControl > 某种位图 > 图像 > MediaClip,但媒体剪辑只能通过存储文件或直接 3d 表面创建。任何事情都会有帮助!这是我第一次尝试在游戏引擎之外写东西。
当前将canvas控件转换为位图的部分:
private async void btnAddOverlay_Click(object sender, RoutedEventArgs e)
{
var bitmap = new RenderTargetBitmap();
await bitmap.RenderAsync(canvasControl);
IBuffer pixelBuffer = await bitmap.GetPixelsAsync();
byte[] pixels = pixelBuffer.ToArray();
SoftwareBitmap outputBitmap = SoftwareBitmap.CreateCopyFromBuffer
(
pixelBuffer,
BitmapPixelFormat.Bgra8,
bitmap.PixelWidth,
bitmap.PixelHeight
);
}
将图像叠加到视频中的旧部分。 (overlayImageFile是存储文件,我只是不知道如何将outputBitmap转换成存储文件来制作媒体剪辑。)
private async void CreateOverlays()
{
// Create a clip from video and add it to the composition
var baseVideoClip = await MediaClip.CreateFromFileAsync(pickedFile);
composition = new MediaComposition();
composition.Clips.Add(baseVideoClip);
// Create a clip from image
var overlayImageClip = await MediaClip.CreateFromImageFileAsync(overlayImageFile,timeSpan);
// Put image in upper left corner, retain its native aspect ratio
Rect imageOverlayPosition;
imageOverlayPosition.Height = mediaElement.ActualHeight / 3;
imageOverlayPosition.Width = (double)imageBitmap.PixelWidth / (double)imageBitmap.PixelHeight * imageOverlayPosition.Height;
imageOverlayPosition.X = 0;
imageOverlayPosition.Y = 0;
// Make the clip from the image an overlay
var imageOverlay = new MediaOverlay(overlayImageClip);
imageOverlay.Position = imageOverlayPosition;
imageOverlay.Opacity = 0.8;
// Make a new overlay layer and add the overlay to it
var overlayLayer = new MediaOverlayLayer();
overlayLayer.Overlays.Add(imageOverlay);
composition.OverlayLayers.Add(overlayLayer);
//Render to MediaElement
mediaElement.Position = TimeSpan.Zero;
mediaStreamSource = composition.GeneratePreviewMediaStreamSource((int)mediaElement.ActualWidth, (int)mediaElement.ActualHeight);
mediaElement.SetMediaStreamSource(mediaStreamSource);
txbNotification.Text = "Overlay creaeted";
}
Windows 媒体剪辑 Class: https://docs.microsoft.com/en-us/uwp/api/windows.media.editing.mediaclip?view=winrt-19041
I just don't know how to convert outputBitmap to a storage file to make a media clip from it.
得到RenderTargetBitmap
后,不需要转换为SoftwareBitmap
。您可以通过BitmapEncoder
将像素数据存储为指定格式的文件。这是方法:
private async void btnAddOverlay_Click(object sender, RoutedEventArgs e)
{
RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
await renderTargetBitmap.RenderAsync(canvasControl);
var pixelBuffer = await renderTargetBitmap.GetPixelsAsync();
var pixels = pixelBuffer.ToArray();
var displayInformation = DisplayInformation.GetForCurrentView();
// Create the file in local folder
var file = await ApplicationData.Current.LocalFolder.CreateFileAsync("TempCanvas.png", CreationCollisionOption.ReplaceExisting);
// Write data
using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied, (uint)renderTargetBitmap.PixelWidth, (uint)renderTargetBitmap.PixelHeight, displayInformation.RawDpiX, displayInformation.RawDpiY, pixels);
await encoder.FlushAsync();
}
}
需要时,您可以使用以下代码获取保存的图片:
var file = await ApplicationData.Current.LocalFolder.GetFileAsync("TempCanvas.png");
这只是另一种可能的方式
如果您使用的是 win2d,则可以使用
MediaClip.CreateFromSurface(IDirect3DSurface, TimeSpan) 函数和
您可以将 canvas 渲染目标直接传递给此方法
这样您就不必将位图保存到文件
因此您必须创建离线 canvas 设备 然后是 canvas 渲染目标 然后在上面画文字 然后将该渲染目标传递给函数 它将生成用于叠加的媒体剪辑