如何在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'.'
问题原因
SaveAsImage()是异步操作,但原代码同步调用后立即读取文件,此时文件可能还未完成写入,导致找不到文件;- 无需通过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
相关产品推荐
相关产品推荐

