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

如何测试Azure Blob中Magick.NET转换后的JPEG存储正确性?

如何验证PNG转JPEG后成功存储到Blob?

问题背景

我需要让应用支持接收任意图片格式,通过Magick.NET-Q8-AnyCPU 13.6.0将其转换为JPEG文件。现有实现代码如下:

var memStream = new MemoryStream();
if (contentType != "image/jpeg")
{
    var convertedImageFile = new MagickImage(imageFile);
    convertedImageFile.Format = MagickFormat.Jpeg;
    convertedImageFile.Write(memStream);
    memStream.Position = 0;
}

var blobClient = containerClient.GetBlobClient(imageFileName);
var headers = new BlobHttpHeaders
{
    ContentType = "image/jpeg"
};

await blobClient.UploadAsync(memStream, headers, metadata);

我编写了测试代码尝试验证转换后的JPEG是否正确存储,但测试失败:

// Arrange
var fileName = "{filePath}/imageTestFile.png";
var containerClient = blobServiceClient.GetBlobContainerClient();

// Act
/* 向端点发起请求并传入.png测试文件。 */

// Assert
var blobClient = containerClient.GetBlobClient(imageId);

var blobClientFile = await blobClient.OpenReadAsync();
var file = File.OpenRead(fileName);

Assert.Equal(blobClientFile, file);

测试报错信息:

Assert.Equal() Failure: Values differ
Expected: 11417
Actual:   33383

现在需要编写正确的测试,确认原PNG经上传转换为JPEG后已成功存储到Blob中。


解决方案

1. 核心问题分析

直接对比原PNG文件流和Blob中的JPEG流必然失败——两者格式不同,文件大小、字节内容完全不一致。你需要验证的是Blob中的文件是原PNG转换后的有效JPEG,且内容匹配,而非和原文件字节相等。

2. 正确的测试实现

步骤1:提前生成预期的JPEG基准文件

在测试初始化阶段,用和业务代码完全一致的Magick.NET逻辑把测试PNG转换成JPEG,作为验证的基准:

// Arrange
var testPngPath = "{filePath}/imageTestFile.png";
var expectedJpegStream = new MemoryStream();

// 复用业务代码的转换逻辑生成预期JPEG
using var originalImage = new MagickImage(testPngPath);
originalImage.Format = MagickFormat.Jpeg;
originalImage.Write(expectedJpegStream);
expectedJpegStream.Position = 0;

var containerClient = blobServiceClient.GetBlobContainerClient();

步骤2:执行上传后验证Blob内容

// Act
/* 向端点发起请求并传入.png测试文件。 */

// Assert
var blobClient = containerClient.GetBlobClient(imageId);
var blobStream = await blobClient.OpenReadAsync();

// 第一步:验证Blob的ContentType确实是JPEG
var blobProperties = await blobClient.GetPropertiesAsync();
Assert.Equal("image/jpeg", blobProperties.Value.ContentType);

// 第二步:对比转换后的字节内容
using var blobMemoryStream = new MemoryStream();
await blobStream.CopyToAsync(blobMemoryStream);
blobMemoryStream.Position = 0;

// 对比基准JPEG和Blob中JPEG的字节数组
Assert.Equal(expectedJpegStream.ToArray(), blobMemoryStream.ToArray());

3. 更严格的视觉验证(可选)

如果担心JPEG压缩参数差异导致字节不匹配,可以对比图片的核心属性或像素哈希:

using var blobImage = new MagickImage(blobStream);
using var expectedImage = new MagickImage(expectedJpegStream);

// 验证图片宽高一致
Assert.Equal(expectedImage.Width, blobImage.Width);
Assert.Equal(expectedImage.Height, blobImage.Height);

// 验证像素哈希一致(忽略微小压缩差异)
var expectedHash = expectedImage.Signature();
var blobHash = blobImage.Signature();
Assert.Equal(expectedHash, blobHash);

4. 修复业务代码的潜在漏洞

你的业务代码存在空流风险:如果传入的是JPEG文件,memStream会是空的,导致上传空文件。补充处理逻辑:

var memStream = new MemoryStream();
if (contentType != "image/jpeg")
{
    var convertedImageFile = new MagickImage(imageFile);
    convertedImageFile.Format = MagickFormat.Jpeg;
    convertedImageFile.Write(memStream);
    memStream.Position = 0;
}
else
{
    // 直接复制原JPEG到内存流
    await imageFile.CopyToAsync(memStream);
    memStream.Position = 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 00:03:25