在 UWP 中将 BitmapImage 转换为字节数组
Convert a BitmapImage to byte array in UWP
如何在 UWP 中将 BitmapImage 对象转换为字节数组?在 .Net 中很容易实现,即使在以前的 WinRT 版本中,在互联网上搜索也没有成功,其中一种解决方案是使用 WriteableBitmap
就像在这个 中提到的那样,但是在当前版本的 UWP,无法从 BitmapImage 构建 WriteableBitmap,是否有解决方法?
既然你是从图像开始的url,我唯一能想到的方法就是获取图像流。为此,RandomAccessStreamReference.CreateFromUri()
方法非常有用。
Windows.Storage.Streams.IRandomAccessStream random = await Windows.Storage.Streams.RandomAccessStreamReference.CreateFromUri(new Uri("http://...")).OpenReadAsync();
然后我们必须解码流以便能够读取所有像素供以后使用。
Windows.Graphics.Imaging.BitmapDecoder decoder = await Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(random);
Windows.Graphics.Imaging.PixelDataProvider pixelData = await decoder.GetPixelDataAsync();
终于可以通过这种方式访问像素缓冲区了。
byte[] bytes = pixelData.DetachPixelData();
是啊,到一个byte[]并不太复杂,我想你可以搞定。我希望它更简单,但事实并非如此。
这段代码实际上更进一步,将 byte[] 转换为 Base64 字符串(用于序列化),但您可以忽略这额外的步骤,对吧?
// using System.Runtime.InteropServices.WindowsRuntime;
private async Task<string> ToBase64(Image control)
{
var bitmap = new RenderTargetBitmap();
await bitmap.RenderAsync(control);
return await ToBase64(bitmap);
}
private async Task<string> ToBase64(WriteableBitmap bitmap)
{
var bytes = bitmap.PixelBuffer.ToArray();
return await ToBase64(bytes, (uint)bitmap.PixelWidth, (uint)bitmap.PixelHeight);
}
private async Task<string> ToBase64(StorageFile bitmap)
{
var stream = await bitmap.OpenAsync(Windows.Storage.FileAccessMode.Read);
var decoder = await BitmapDecoder.CreateAsync(stream);
var pixels = await decoder.GetPixelDataAsync();
var bytes = pixels.DetachPixelData();
return await ToBase64(bytes, (uint)decoder.PixelWidth, (uint)decoder.PixelHeight, decoder.DpiX, decoder.DpiY);
}
private async Task<string> ToBase64(RenderTargetBitmap bitmap)
{
var bytes = (await bitmap.GetPixelsAsync()).ToArray();
return await ToBase64(bytes, (uint)bitmap.PixelWidth, (uint)bitmap.PixelHeight);
}
private async Task<string> ToBase64(byte[] image, uint height, uint width, double dpiX = 96, double dpiY = 96)
{
// encode image
var encoded = new InMemoryRandomAccessStream();
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, encoded);
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, height, width, dpiX, dpiY, image);
await encoder.FlushAsync();
encoded.Seek(0);
// read bytes
var bytes = new byte[encoded.Size];
await encoded.AsStream().ReadAsync(bytes, 0, bytes.Length);
// create base64
return Convert.ToBase64String(bytes);
}
private async Task<ImageSource> FromBase64(string base64)
{
// read stream
var bytes = Convert.FromBase64String(base64);
var image = bytes.AsBuffer().AsStream().AsRandomAccessStream();
// decode image
var decoder = await BitmapDecoder.CreateAsync(image);
image.Seek(0);
// create bitmap
var output = new WriteableBitmap((int)decoder.PixelHeight, (int)decoder.PixelWidth);
await output.SetSourceAsync(image);
return output;
}
这是重要的部分:
var bytes = (await bitmap.GetPixelsAsync()).ToArray();
我想你可能会喜欢看它的上下文。
祝你好运。
如何在 UWP 中将 BitmapImage 对象转换为字节数组?在 .Net 中很容易实现,即使在以前的 WinRT 版本中,在互联网上搜索也没有成功,其中一种解决方案是使用 WriteableBitmap
就像在这个
既然你是从图像开始的url,我唯一能想到的方法就是获取图像流。为此,RandomAccessStreamReference.CreateFromUri()
方法非常有用。
Windows.Storage.Streams.IRandomAccessStream random = await Windows.Storage.Streams.RandomAccessStreamReference.CreateFromUri(new Uri("http://...")).OpenReadAsync();
然后我们必须解码流以便能够读取所有像素供以后使用。
Windows.Graphics.Imaging.BitmapDecoder decoder = await Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(random);
Windows.Graphics.Imaging.PixelDataProvider pixelData = await decoder.GetPixelDataAsync();
终于可以通过这种方式访问像素缓冲区了。
byte[] bytes = pixelData.DetachPixelData();
是啊,到一个byte[]并不太复杂,我想你可以搞定。我希望它更简单,但事实并非如此。
这段代码实际上更进一步,将 byte[] 转换为 Base64 字符串(用于序列化),但您可以忽略这额外的步骤,对吧?
// using System.Runtime.InteropServices.WindowsRuntime;
private async Task<string> ToBase64(Image control)
{
var bitmap = new RenderTargetBitmap();
await bitmap.RenderAsync(control);
return await ToBase64(bitmap);
}
private async Task<string> ToBase64(WriteableBitmap bitmap)
{
var bytes = bitmap.PixelBuffer.ToArray();
return await ToBase64(bytes, (uint)bitmap.PixelWidth, (uint)bitmap.PixelHeight);
}
private async Task<string> ToBase64(StorageFile bitmap)
{
var stream = await bitmap.OpenAsync(Windows.Storage.FileAccessMode.Read);
var decoder = await BitmapDecoder.CreateAsync(stream);
var pixels = await decoder.GetPixelDataAsync();
var bytes = pixels.DetachPixelData();
return await ToBase64(bytes, (uint)decoder.PixelWidth, (uint)decoder.PixelHeight, decoder.DpiX, decoder.DpiY);
}
private async Task<string> ToBase64(RenderTargetBitmap bitmap)
{
var bytes = (await bitmap.GetPixelsAsync()).ToArray();
return await ToBase64(bytes, (uint)bitmap.PixelWidth, (uint)bitmap.PixelHeight);
}
private async Task<string> ToBase64(byte[] image, uint height, uint width, double dpiX = 96, double dpiY = 96)
{
// encode image
var encoded = new InMemoryRandomAccessStream();
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, encoded);
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, height, width, dpiX, dpiY, image);
await encoder.FlushAsync();
encoded.Seek(0);
// read bytes
var bytes = new byte[encoded.Size];
await encoded.AsStream().ReadAsync(bytes, 0, bytes.Length);
// create base64
return Convert.ToBase64String(bytes);
}
private async Task<ImageSource> FromBase64(string base64)
{
// read stream
var bytes = Convert.FromBase64String(base64);
var image = bytes.AsBuffer().AsStream().AsRandomAccessStream();
// decode image
var decoder = await BitmapDecoder.CreateAsync(image);
image.Seek(0);
// create bitmap
var output = new WriteableBitmap((int)decoder.PixelHeight, (int)decoder.PixelWidth);
await output.SetSourceAsync(image);
return output;
}
这是重要的部分:
var bytes = (await bitmap.GetPixelsAsync()).ToArray();
我想你可能会喜欢看它的上下文。
祝你好运。