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

如何在C# MAUI .NET 7.0中从ImageSource获取Base64字符串

MAUI中SyncFusion签名板ImageSource转Base64失败

问题背景

在C# MAUI .NET 7.0环境中,使用SyncFusion Signature Pad组件的ToImageSource()方法获取到StreamImageSource对象,尝试将其转换为Base64字符串时遇到问题。最初尝试将ImageSource赋值给Image控件immagine的Source属性,再调用SaveAsImage()方法保存,但读取文件时抛出System.IO.FileNotFoundException异常。

原尝试代码

private void btnConfermaClicked(object sender, EventArgs e)
{
    Log.Verbose("Signature confirm clicked");

    ImageSource source_firma = signaturePad.ToImageSource();
    Log.Debug($"Signature as {source_firma.GetType()}");

    immagine.Source = source_firma;

    // Generate random file name
    string fileName = Path.GetRandomFileName() + ".png";

    string folderName = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
    string path = Path.Combine(folderName, fileName);
    Log.Debug($"Random path: {path}");

    Log.Verbose("Start saving image");
    try
    {
        immagine.SaveAsImage(path);
    } catch (Exception ex)
    {
        Log.Error($"Error while saving image: {ex.Message}");
    }
    Log.Verbose("Done saving image");

    byte[] bytes = File.ReadAllBytes(path);
    string base64 = Convert.ToBase64String(bytes);
    Log.Debug($"Signature base64: {base64}");
} 

日志输出

[0:] [19:15:49 VRB] Signature confirm clicked
[0:] [19:15:49 DBG] Signature as Microsoft.Maui.Controls.StreamImageSource
[0:] [19:15:49 DBG] Random path: /data/user/0/com.companyname.iglogestorepresenze/files/eaiktmuj.0gr.png
[0:] [19:15:49 VRB] Start saving image
[gestorepresenz] Explicit concurrent copying GC freed 12995(775KB) AllocSpace objects, 7(5008KB) LOS objects, 84% free, 4446KB/28MB, paused 32us total 14.729ms
[0:] [19:15:49 VRB] Done saving image
**System.IO.FileNotFoundException:** 'Could not find file '/data/user/0/com.companyname.iglogestorepresenze/files/eaiktmuj.0gr.png'.'

问题原因

  1. SaveAsImage()是异步操作,但原代码同步调用后立即读取文件,此时文件可能还未完成写入,导致找不到文件;
  2. 无需通过Image控件中转保存,直接从StreamImageSource获取流即可转换为Base64,步骤更简洁且避免异步问题。

解决方案

方案1:使用异步保存方法(修正原思路)

将方法改为异步,调用SaveAsImageAsync()并等待完成后再读取文件:

private async void btnConfermaClicked(object sender, EventArgs e)
{
    Log.Verbose("Signature confirm clicked");

    ImageSource source_firma = signaturePad.ToImageSource();
    Log.Debug($"Signature as {source_firma.GetType()}");

    immagine.Source = source_firma;

    string fileName = Path.GetRandomFileName() + ".png";
    string folderName = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
    string path = Path.Combine(folderName, fileName);
    Log.Debug($"Random path: {path}");

    Log.Verbose("Start saving image");
    try
    {
        await immagine.SaveAsImageAsync(path);
    } catch (Exception ex)
    {
        Log.Error($"Error while saving image: {ex.Message}");
        return; // 保存失败直接返回,避免后续读取错误
    }
    Log.Verbose("Done saving image");

    if (File.Exists(path))
    {
        byte[] bytes = File.ReadAllBytes(path);
        string base64 = Convert.ToBase64String(bytes);
        Log.Debug($"Signature base64: {base64}");
        // 可选:删除临时文件
        File.Delete(path);
    }
    else
    {
        Log.Error("File still not found after saving");
    }
}

方案2:直接从StreamImageSource获取流转换Base64(更高效)

跳过Image控件,直接从StreamImageSource获取流并转换为Base64,无需写入文件:

private async void btnConfermaClicked(object sender, EventArgs e)
{
    Log.Verbose("Signature confirm clicked");

    ImageSource source_firma = signaturePad.ToImageSource();
    Log.Debug($"Signature as {source_firma.GetType()}");

    if (source_firma is StreamImageSource streamSource)
    {
        using (var stream = await streamSource.Stream(CancellationToken.None))
        {
            using (var memoryStream = new MemoryStream())
            {
                await stream.CopyToAsync(memoryStream);
                byte[] bytes = memoryStream.ToArray();
                string base64 = Convert.ToBase64String(bytes);
                Log.Debug($"Signature base64: {base64}");
            }
        }
    }
    else
    {
        Log.Error("Unsupported ImageSource type");
    }
}

补充说明

immagine是XAML中定义的Image控件,正确代码应为:<Image x:Name="immagine" />(注:原代码中id应为MAUI标准的x:Name属性,用于标识控件)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 00:05:04