-修复结构探查器的图片查看器无法查看CMYK图像的问题

This commit is contained in:
WMJ
2026-02-15 10:38:53 +08:00
parent 4e7dcf6b7f
commit 7aa6543aac
@@ -18,13 +18,24 @@ namespace PDFPatcher.Functions
_ImageBox.Image = bmp.ToBitmap();
}
else {
FIBITMAP b = default;
try {
using FreeImageBitmap bmp = FreeImageHelper.CreateFromBytes(bytes);
_ImageBox.Image = bmp.ToBitmap();
var isCmyk = iTextSharp.text.pdf.PdfName.DEVICECMYK.Equals(image.ColorSpace);
using var ms = new System.IO.MemoryStream(bytes);
b = FreeImage.LoadFromStream(ms, isCmyk ? FREE_IMAGE_LOAD_FLAGS.TIFF_CMYK | FREE_IMAGE_LOAD_FLAGS.JPEG_CMYK : FREE_IMAGE_LOAD_FLAGS.DEFAULT);
if (isCmyk) {
b = ConvertCmykToRgb(b, image.InvertCmyk);
}
_ImageBox.Image = FreeImage.GetBitmap(b);
}
catch (System.Exception ex) {
this.ErrorBox("无法加载图片", ex);
}
finally {
if (!b.IsNull) {
FreeImage.Unload(b);
}
}
}
}
@@ -62,5 +73,73 @@ namespace PDFPatcher.Functions
break;
}
}
static FIBITMAP ConvertCmykToRgb(FIBITMAP cmykDib, bool invert) {
int width = (int)FreeImage.GetWidth(cmykDib);
int height = (int)FreeImage.GetHeight(cmykDib);
FIBITMAP rgbDib = FreeImage.Allocate(width, height, 24, 0, 0, 0);
FIBITMAP cChannel = FreeImage.GetChannel(cmykDib, FREE_IMAGE_COLOR_CHANNEL.FICC_BLUE);
FIBITMAP mChannel = FreeImage.GetChannel(cmykDib, FREE_IMAGE_COLOR_CHANNEL.FICC_GREEN);
FIBITMAP yChannel = FreeImage.GetChannel(cmykDib, FREE_IMAGE_COLOR_CHANNEL.FICC_RED);
FIBITMAP kChannel = FreeImage.GetChannel(cmykDib, FREE_IMAGE_COLOR_CHANNEL.FICC_ALPHA);
unsafe {
var cPtr = (byte*)FreeImage.GetBits(cChannel);
var mPtr = (byte*)FreeImage.GetBits(mChannel);
var yPtr = (byte*)FreeImage.GetBits(yChannel);
var kPtr = (byte*)FreeImage.GetBits(kChannel);
var rgbPtr = (byte*)FreeImage.GetBits(rgbDib);
var pitch = (int)FreeImage.GetPitch(rgbDib);
for (int y = 0; y < height; y++) {
int rowOffset = y * pitch;
int srcBaseIdx = y * width; // 假设通道也是连续的,无行填充(通常 FreeImage 通道如此)
for (int x = 0; x < width; x++) {
int srcIdx = srcBaseIdx + x;
int dstIdx = rowOffset + x * 3;
// 读取原始值
int c = cPtr[srcIdx];
int m = mPtr[srcIdx];
int yVal = yPtr[srcIdx];
int k = kPtr[srcIdx];
// 如果需要取反(之前的逻辑)
if (invert) {
c = 255 - c;
m = 255 - m;
yVal = 255 - yVal;
k = 255 - k;
}
// 计算红色: R = (255 - C) * (255 - K) / 255
int r_val = ((255 - c) * (255 - k)) / 255;
// 计算绿色: G = (255 - M) * (255 - K) / 255
int g_val = ((255 - m) * (255 - k)) / 255;
// 计算蓝色: B = (255 - Y) * (255 - K) / 255
int b_val = ((255 - yVal) * (255 - k)) / 255;
// 写入 RGB (BGR 顺序)
rgbPtr[dstIdx + 0] = (byte)b_val;
rgbPtr[dstIdx + 1] = (byte)g_val;
rgbPtr[dstIdx + 2] = (byte)r_val;
}
}
}
FreeImage.Unload(cChannel);
FreeImage.Unload(mChannel);
FreeImage.Unload(yChannel);
FreeImage.Unload(kChannel);
FreeImage.Unload(cmykDib);
return rgbDib;
}
}
}