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

如何拼接两个Base64图片字符串并还原为完整图片文件?

问题分析与解决方案

你的核心问题有两个:一是代码里的低级拼写错误,二是直接拼接两个独立JPEG文件的字节数组无法生成合法图片——因为每个JPEG都是完整的文件格式,包含SOI(起始标记)和EOI(结束标记),拼接后会变成两个JPEG的堆叠,不是单一合法的图片文件。

第一步:修正代码里的低级错误

你的代码中data2的转换写错了,用了convert而不是convert2,导致两个字节数组重复,先修正这个:

// 原错误代码
byte[] data2 = Convert.FromBase64String(convert);
// 修正为
byte[] data2 = Convert.FromBase64String(convert2);

但即使修正了这个,直接拼接JPEG字节数组依然无法得到正确图片,下面是两种可行的解决方案:


方案一:前端先合并Canvas再传输(优先推荐)

既然是同一个页面的不同区域,直接在前端把两个canvas合并成一个大canvas,再转成base64。如果合并后的base64字符串超过32K,再对这个单一大base64进行分块传输,而不是分块截图。

修改前端JS代码:

// 新增合并两个Canvas的函数
async function MergeAndGetFullScreenshot(headerId, footerId) {
    // 获取两个区域的canvas
    const headerCanvas = await html2canvas(document.getElementById(headerId), { allowTaint: true, useCors: true, background: "#00FFFFFF" });
    const footerCanvas = await html2canvas(document.getElementById(footerId), { allowTaint: true, useCors: true, background: "#00FFFFFF" });

    // 创建一个大Canvas,高度是两个Canvas的总和,宽度取较大的那个
    const fullWidth = Math.max(headerCanvas.width, footerCanvas.width);
    const fullHeight = headerCanvas.height + footerCanvas.height;
    const fullCanvas = document.createElement('canvas');
    fullCanvas.width = fullWidth;
    fullCanvas.height = fullHeight;
    const ctx = fullCanvas.getContext('2d');

    // 绘制头部和尾部到大Canvas
    ctx.drawImage(headerCanvas, 0, 0);
    ctx.drawImage(footerCanvas, 0, headerCanvas.height);

    // 转成base64,如果超过32K,就分块返回
    const base64 = fullCanvas.toDataURL('image/jpeg', 0.5);
    const chunkSize = 30000; // 留余量,小于32K
    const chunks = [];
    for (let i = 0; i < base64.length; i += chunkSize) {
        chunks.push(base64.slice(i, i + chunkSize));
    }
    return chunks;
}

Blazor后端代码:

async Task SaveScreenShotToFile()
{
    // 获取分块的base64数组
    var base64Chunks = await JS.InvokeAsync<List<string>>("MergeAndGetFullScreenshot", "divRaHeader", "divRaFooter");
    
    if (base64Chunks == null || !base64Chunks.Any()) return;

    // 拼接所有分块
    string fullBase64 = string.Join("", base64Chunks);
    string cleanBase64 = fullBase64.Replace("data:image/jpeg;base64,", string.Empty);
    byte[] imageData = Convert.FromBase64String(cleanBase64);

    var filepath = @"C:\VS2022\AppMain\wwwroot\Image.jpg";
    await File.WriteAllBytesAsync(filepath, imageData);
}

方案二:后端接收独立图片,用图片处理库合并(备选)

如果必须分块获取截图(比如区域太大无法前端合并),可以在后端使用图片处理库(如SixLabors.ImageSharp)将两张图片垂直拼接成一张。

示例(先安装NuGet包:SixLabors.ImageSharp):

using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;

async Task SaveScreenShotToFile()
{
    string headerBase64 = await JS.InvokeAsync<string>("GetDivScreenShot", "divRaHeader");
    string footerBase64 = await JS.InvokeAsync<string>("GetDivScreenShot", "divRaFooter");

    if (string.IsNullOrEmpty(headerBase64) || string.IsNullOrEmpty(footerBase64)) return;

    // 解码两张图片
    byte[] headerBytes = Convert.FromBase64String(headerBase64.Replace("data:image/jpeg;base64,", string.Empty));
    byte[] footerBytes = Convert.FromBase64String(footerBase64.Replace("data:image/jpeg;base64,", string.Empty));

    using (var headerImage = Image.Load(headerBytes))
    using (var footerImage = Image.Load(footerBytes))
    {
        // 创建合并后的图片
        int fullWidth = Math.Max(headerImage.Width, footerImage.Width);
        int fullHeight = headerImage.Height + footerImage.Height;
        using (var fullImage = new Image<Rgba32>(fullWidth, fullHeight))
        {
            // 绘制头部和尾部
            fullImage.Mutate(ctx =>
            {
                ctx.DrawImage(headerImage, new Point(0, 0), 1f);
                ctx.DrawImage(footerImage, new Point(0, headerImage.Height), 1f);
            });

            // 保存到文件
            var filepath = @"C:\VS2022\AppMain\wwwroot\Image.jpg";
            await fullImage.SaveAsJpegAsync(filepath);
        }
    }
}

注:System.Drawing.Common在.NET Core/.NET 5+的非Windows平台有兼容性问题,推荐使用跨平台的ImageSharp。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 10:43:19