You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UWP中如何从Base64字符串还原图像?

问题:Base64字符串还原图像失败

我正在开发一款支持Windows Ink绘图与图片粘贴的笔记应用,希望将图片与墨迹保存至单个文件,因此将图像转换为Base64字符串以便序列化。但在从该字符串还原图像时遇到问题:

图像转Base64字符串的代码

var decoder = await BitmapDecoder.CreateAsync(imageStream);
var pixels = await decoder.GetPixelDataAsync();
var bytes = pixels.DetachPixelData();

base64String = Convert.ToBase64String(bytes);

尝试还原图像的代码(无法正常工作,图像未添加到redCanvas)

var bytes = Convert.FromBase64String(base64String);

BitmapImage bitmapImage = new BitmapImage();
using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream())
{
    await stream.WriteAsync(bytes.AsBuffer());
    stream.Seek(0);
    bitmapImage.SetSource(stream);
}
Image image = new Image();

image.Source = bitmapImage;

// Add the image to a second canvas
redCanvas.Children.Add(image);

粘贴图片并生成Base64字符串的完整代码

private async Task myButton_ClickAsync(object sender, RoutedEventArgs e)
{
    var dataPackageView = Windows.ApplicationModel.DataTransfer.Clipboard.GetContent();
    if (dataPackageView.Contains(StandardDataFormats.Bitmap))
    {
        IRandomAccessStreamReference imageReceived = null;
        imageReceived = await dataPackageView.GetBitmapAsync();
        if (imageReceived != null)
        {
            using (var imageStream = await imageReceived.OpenReadAsync())
            {
                var bitmapImage = new BitmapImage();
                bitmapImage.SetSource(imageStream);

                var decoder = await BitmapDecoder.CreateAsync(imageStream);
                var pixels = await decoder.GetPixelDataAsync();
                var bytes = pixels.DetachPixelData();

                base64String = Convert.ToBase64String(bytes);

                TextBox_Image_Base64.Text = base64;
         
                Image image = new Image();
                        
                // Add the image to a list of Images
                ListImages.Add(image);

                blueCanvas.Children.Add(image);

                image.Source = bitmapImage;

                TextBlock_Status.Text = "Status : Image is retrieved from the 
                                                 clipboard and pasted successfully.";
            }
        }
    }
    else
    {
        TextBlock_Status.Text = "Status : Bitmap format is not available in clipboard";
    }
}

请问如何解决从Base64字符串还原图像的问题?


解决方案

问题核心是你仅保存了图像的原始像素数据,没有包含图像格式编码信息。GetPixelDataAsync()返回的是未编码的像素字节(比如RGBA原始数据),而BitmapImage需要完整的编码图像流(如PNG、JPG格式)才能识别,直接写入原始像素字节无法被解析。

修正方案1:保存完整图像编码流(推荐)

不需要解码像素,直接把原始图像流转换为Base64,还原时直接复用原有逻辑即可。

修改图像转Base64的代码

using (var imageStream = await imageReceived.OpenReadAsync())
{
    // 读取完整图像流到字节数组
    var buffer = new byte[imageStream.Size];
    await imageStream.ReadAsync(buffer.AsBuffer(), (uint)imageStream.Size, InputStreamOptions.None);
    base64String = Convert.ToBase64String(buffer);

    // 保留原有显示图像、更新状态等逻辑
}

还原图像代码(无需修改)

var bytes = Convert.FromBase64String(base64String);

BitmapImage bitmapImage = new BitmapImage();
using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream())
{
    await stream.WriteAsync(bytes.AsBuffer());
    stream.Seek(0);
    bitmapImage.SetSource(stream);
}
Image image = new Image();
image.Source = bitmapImage;
redCanvas.Children.Add(image);

修正方案2:若必须保存像素数据,还原时重新编码

如果因需求必须保存原始像素数据,需要在还原时将像素数据重新编码为标准图像格式,同时需提前保存图像的元数据(宽度、高度、像素格式等)。

还原图像的代码修改

var bytes = Convert.FromBase64String(base64String);
// 需提前保存图像元数据,以下为示例值,实际从存储的元数据中读取
uint width = 1920;
uint height = 1080;
BitmapPixelFormat pixelFormat = BitmapPixelFormat.Rgba8;
BitmapAlphaMode alphaMode = BitmapAlphaMode.Straight;

BitmapImage bitmapImage = new BitmapImage();
using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream())
{
    // 创建PNG编码器
    var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
    encoder.SetPixelData(pixelFormat, alphaMode, width, height, 96, 96, bytes);
    await encoder.FlushAsync();
    
    stream.Seek(0);
    bitmapImage.SetSource(stream);
}

Image image = new Image();
image.Source = bitmapImage;
redCanvas.Children.Add(image);

额外注意事项

  1. 方案1更高效简洁,适合绝大多数场景,保存的Base64体积与原图像一致,还原逻辑无需额外处理。
  2. 方案2需要额外存储图像元数据,否则无法正确编码还原。
  3. 原粘贴代码中TextBox_Image_Base64.Text = base64;存在变量名错误,应改为base64String,避免运行时异常。

内容的提问来源于stack exchange,提问作者Magnus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 10:15:50