在Metro Windows 8中,将ImageSource转换为WriteableBitmap可以通过以下步骤实现:
以下是一个示例代码:
// 将ImageSource转换为WriteableBitmap
private async Task<WriteableBitmap> ConvertImageSourceToWriteableBitmap(ImageSource imageSource)
{
WriteableBitmap writeableBitmap = null;
if (imageSource != null)
{
var stream = new InMemoryRandomAccessStream();
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
var pixelData = await imageSource.ToPixelDataAsync();
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, (uint)imageSource.PixelWidth, (uint)imageSource.PixelHeight, 96.0, 96.0, pixelData);
await encoder.FlushAsync();
stream.Seek(0);
var bitmapImage = new BitmapImage();
bitmapImage.SetSource(stream);
writeableBitmap = new WriteableBitmap(bitmapImage.PixelWidth, bitmapImage.PixelHeight);
stream.Seek(0);
await writeableBitmap.SetSourceAsync(stream);
}
return writeableBitmap;
}
在这个示例代码中,我们首先创建了一个InMemoryRandomAccessStream对象,然后使用BitmapEncoder将ImageSource转换为PNG格式的数据,并将其写入到InMemoryRandomAccessStream对象中。接着,我们使用BitmapImage对象将InMemoryRandomAccessStream对象中的数据读取出来,并将其设置为WriteableBitmap对象的源。最后,我们返回WriteableBitmap对象。
需要注意的是,这个示例代码中的ToPixelDataAsync()方法是扩展方法,需要自己实现。具体实现可以参考以下代码:
public static class ImageSourceExtensions
{
public static async Task<byte[]> ToPixelDataAsync(this ImageSource imageSource)
{
byte[] pixelData = null;
if (imageSource != null)
{
var randomAccessStream = new InMemoryRandomAccessStream();
var bitmapEncoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, randomAccessStream);
var softwareBitmap = await imageSource.ToSoftwareBitmapAsync();
bitmapEncoder.SetSoftwareBitmap(softwareBitmap);
await bitmapEncoder.FlushAsync();
pixelData = (await randomAccessStream.ToArrayAsync()).ToArray();
}
return pixelData;
}
private static async Task<SoftwareBitmap> ToSoftwareBitmapAsync(this ImageSource imageSource)
{
SoftwareBitmap softwareBitmap = null;
if (imageSource is SoftwareBitmapSource softwareBitmapSource)
{
softwareBitmap = softwareBitmapSource.SoftwareBitmap;
}
else if (imageSource is WriteableBitmap writeableBitmap)
{
softwareBitmap = SoftwareBitmap.CreateCopyFromBuffer(writeableBitmap.PixelBuffer, BitmapPixelFormat.Bgra8, writeableBitmap.PixelWidth, writeableBitmap.PixelHeight);
}
else if (imageSource is BitmapImage bitmapImage)
{
softwareBitmap = await bitmapImage.ToSoftwareBitmapAsync();
}
return softwareBitmap;
}
private static async Task<SoftwareBitmap> ToSoftwareBitmapAsync(this BitmapImage bitmapImage)
{
SoftwareBitmap softwareBitmap = null;
if (bitmapImage != null)
{
var randomAccessStream = new InMemoryRandomAccessStream();
var bitmapEncoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, randomAccessStream);
bitmapEncoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, (uint)bitmapImage.PixelWidth, (uint)bitmapImage.PixelHeight, 96.0, 96.0, await bitmapImage.ToPixelDataAsync());
await bitmapEncoder.FlushAsync();
randomAccessStream.Seek(0);
softwareBitmap = await BitmapDecoder.CreateAsync(randomAccessStream).AsTask().ContinueWith(async (task) =>
{
var bitmapDecoder = task.Result;
return await bitmapDecoder.GetSoftwareBitmapAsync();
}).Unwrap().ConfigureAwait(false);
}
return softwareBitmap;
}
private static async Task<byte[]> ToArrayAsync(this IRandomAccessStream randomAccessStream)
{
byte[] data = new byte[randomAccessStream.Size];
await randomAccessStream.ReadAsync(data.AsBuffer(), (uint)randomAccessStream.Size, InputStreamOptions.None);
return data;
}
}
这个扩展方法包含了ImageSource对象到SoftwareBitmap对象的转换,以及SoftwareBitmap对象到字节数组的转换。
领取专属 10元无门槛券
手把手带您无忧上云