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

如何用C#与jQuery判断图片是否一致?Blazor对比异常问题

问题描述

使用VS2022、C#、Blazor和jQuery开发时,先将本地路径C:\Images\defaultImage.png加载到页面Canvas区域:

<canvas id="CanvasId" @ref="canvasElement"></canvas>
await JS.InvokeVoidAsync("loadImageOnCanvas", "CanvasId", "/scripts/defaultImage.png");

图片存入数据库后,日后从数据库取回并加载到Canvas,需要判断该图片是否与本地C:\Images\defaultImage.png一致,但对比结果始终不相等——Canvas中的图片字节数总是比原文件大1KB左右。用于对比的代码如下:

// Retrieve the image that was loaded on canvas
var canvasImage = await JS.InvokeAsync<string>("captureCanvasImage", "CanvasId");
canvasImage = canvasImage.Replace("data:image/png;base64,", String.Empty);
               
// byte[27980]
byte[] imageOnCanvas_Bytes = Convert.FromBase64String(canvasImage);
    
// byte[26978]
byte[] defaultImage_Bytes = File.ReadAllBytes("wwwroot/scripts/defaultImage.png");
                    
// Compare as string returns FALSE  
var result = canvasImage == Convert.ToBase64String(defaultImage_Bytes);
                     
// Compare byte arrays returns FALSE
var result2 = imageOnCanvas_Bytes.SequenceEqual(defaultImage_Bytes);
原因分析
  • Canvas导出PNG时会重新编码图像,即使像素完全一致,编码参数(如压缩级别、颜色配置)和原文件也可能存在差异,导致字节数和内容不同。
  • 原PNG文件可能包含元数据(如EXIF信息、注释),而Canvas导出的PNG不会保留这些额外数据,或会添加自身默认的元数据。
  • 浏览器加载图片到Canvas的过程中,可能会进行颜色空间转换或像素格式调整,再次导出时就会和原文件产生差异。
解决方案

方案1:基于像素数据对比哈希值

不直接对比文件字节,而是对比Canvas图像与原图像的像素数据哈希:

  1. 编写JS函数获取像素哈希:
// 获取Canvas图像的像素哈希
function getCanvasPixelHash(canvasId) {
    const canvas = document.getElementById(canvasId);
    const ctx = canvas.getContext('2d');
    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    const pixels = imageData.data;
    
    let hash = 0;
    // 累加所有像素的RGBA值计算哈希(小图足够用,复杂场景可换MD5等算法)
    for (let i = 0; i < pixels.length; i += 4) {
        hash += pixels[i] + pixels[i+1] + pixels[i+2] + pixels[i+3];
    }
    return hash.toString(16);
}

// 获取本地图片的像素哈希
function getLocalImagePixelHash(imageUrl) {
    return new Promise((resolve, reject) => {
        const img = new Image();
        img.crossOrigin = 'anonymous';
        img.onload = function() {
            const tempCanvas = document.createElement('canvas');
            tempCanvas.width = img.width;
            tempCanvas.height = img.height;
            const ctx = tempCanvas.getContext('2d');
            ctx.drawImage(img, 0, 0);
            
            const imageData = ctx.getImageData(0, 0, tempCanvas.width, tempCanvas.height);
            const pixels = imageData.data;
            
            let hash = 0;
            for (let i = 0; i < pixels.length; i += 4) {
                hash += pixels[i] + pixels[i+1] + pixels[i+2] + pixels[i+3];
            }
            resolve(hash.toString(16));
        };
        img.onerror = reject;
        img.src = imageUrl;
    });
}
  1. 在Blazor中调用对比:
var canvasHash = await JS.InvokeAsync<string>("getCanvasPixelHash", "CanvasId");
var localImageHash = await JS.InvokeAsync<string>("getLocalImagePixelHash", "/scripts/defaultImage.png");

var isEqual = canvasHash == localImageHash;

方案2:精确像素对比(适合小尺寸图片)

由于你的图片尺寸仅241px×154px,可以直接对比每个像素的RGBA值:

function compareCanvasAndLocalImage(canvasId, imageUrl) {
    return new Promise((resolve, reject) => {
        const img = new Image();
        img.crossOrigin = 'anonymous';
        img.onload = function() {
            const canvas = document.getElementById(canvasId);
            // 先对比尺寸
            if (canvas.width !== img.width || canvas.height !== img.height) {
                resolve(false);
                return;
            }
            
            const ctx = canvas.getContext('2d');
            const canvasPixels = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
            
            const tempCanvas = document.createElement('canvas');
            tempCanvas.width = img.width;
            tempCanvas.height = img.height;
            const tempCtx = tempCanvas.getContext('2d');
            tempCtx.drawImage(img, 0, 0);
            const localPixels = tempCtx.getImageData(0, 0, tempCanvas.width, tempCanvas.height).data;
            
            // 逐像素对比RGBA值
            for (let i = 0; i < canvasPixels.length; i++) {
                if (canvasPixels[i] !== localPixels[i]) {
                    resolve(false);
                    return;
                }
            }
            resolve(true);
        };
        img.onerror = reject;
        img.src = imageUrl;
    });
}

Blazor中调用:

var isEqual = await JS.InvokeAsync<bool>("compareCanvasAndLocalImage", "CanvasId", "/scripts/defaultImage.png");

方案3:预存原图片像素哈希到数据库

首次将图片存入数据库时,提前计算原图片的像素哈希并一同存储。日后从数据库取回图片加载到Canvas后,直接对比Canvas的像素哈希与数据库中存储的哈希值,无需每次读取本地文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 02:15:12