You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

在SkiaSharp中生成新图像(如缩放)时,如何保存带原图像ICC配置文件?

搞定这个问题其实很清晰,核心就是先把原图像的ICC配置文件提取出来,再在保存处理后的新图像时把它嵌回去。我给你拆解成具体步骤和代码示例,一看就懂:

1. 提取原图像的ICC配置文件

首先加载原图像时,我们要从它的颜色空间里导出ICC数据。SkiaSharp的SKBitmapSKImage都有ColorSpace属性,通过它就能拿到ICC配置文件的字节数组:

// 加载原图像文件
using var originalBitmap = SKBitmap.Decode("your-original-image.jpg");
byte[] originalIccProfile = null;

// 检查原图像是否带有ICC配置文件
if (originalBitmap.ColorSpace != null)
{
    // 将ColorSpace转换为ICC字节数组
    using var iccData = originalBitmap.ColorSpace.ToIccProfileData();
    originalIccProfile = iccData.ToArray();
}
2. 执行图像处理(以缩放为例)

接下来正常做你的图像操作,比如缩放。这一步处理后的新图像本身不会继承原ICC,所以我们要把刚才拿到的originalIccProfile存好:

// 定义缩放后的尺寸(这里示例为原尺寸的50%)
int scaledWidth = originalBitmap.Width / 2;
int scaledHeight = originalBitmap.Height / 2;

// 创建缩放后的Bitmap,指定缩放质量
using var scaledBitmap = originalBitmap.Resize(
    new SKImageInfo(scaledWidth, scaledHeight), 
    SKFilterQuality.High
);
3. 保存新图像时嵌入ICC配置文件

最后保存的时候,要通过编码器的选项把ICC配置文件加进去。不同图像格式对应不同的编码器(比如JPEG用SKJpegEncoderOptions,PNG用SKPngEncoderOptions),它们大多都有IccProfile属性可以设置:

// 根据目标格式创建编码器选项
var encodeOptions = new SKJpegEncoderOptions();
// 如果是PNG就用:var encodeOptions = new SKPngEncoderOptions();

// 如果原图像有ICC配置文件,就嵌入到新图像里
if (originalIccProfile != null)
{
    encodeOptions.IccProfile = originalIccProfile;
}

// 将缩放后的Bitmap转成SKImage并编码保存
using var scaledImage = SKImage.FromBitmap(scaledBitmap);
using var encodedData = scaledImage.Encode(encodeOptions);
using var outputStream = File.OpenWrite("scaled-image-with-icc.jpg");
encodedData.SaveTo(outputStream);
额外注意事项
  • 格式兼容性:不是所有图像格式都支持ICC嵌入,目前JPEG、PNG、WebP都是支持的,而BMP这类格式可能不支持,要根据你的目标格式选择对应的编码器。
  • 资源释放:SkiaSharp的图像对象(SKBitmapSKImageSKData)都实现了IDisposable,一定要用using语句管理,避免内存泄漏。
  • SKImage的情况:如果你的流程是用SKImage而不是SKBitmap,提取ICC的逻辑是一样的——originalImage.ColorSpace?.ToIccProfileData()?.ToArray()即可。

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

火山引擎 最新活动