From 365f3ba8f955b3b29f74e5e950074b52180da6a8 Mon Sep 17 00:00:00 2001 From: xiaoqidun Date: Fri, 16 Oct 2026 09:25:35 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E5=9B=BE=E5=83=8F=E9=A2=9C=E8=89=B2):=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=9B=BE=E5=83=8F=E9=A2=9C=E8=89=B2=E8=BD=AC?= =?UTF-8?q?=E6=8D=A2=E6=80=A7=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/base/image/color.go | 18 +++++++++++++++--- internal/base/image/tiff_profile.go | 3 ++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/internal/base/image/color.go b/internal/base/image/color.go index 6bc3869..363e223 100644 --- a/internal/base/image/color.go +++ b/internal/base/image/color.go @@ -249,7 +249,7 @@ func jpegColorProfile(ctx context.Context, data []byte, model color.Model) ([]by return profile, nil } -// jpegDisplayImage 统一JPEG显示变换,保留源分量并使用文档内嵌ICC +// jpegDisplayImage 统一JPEG显示变换,保留源分量并精确复用相邻同色的ICC结果 // 入参: ctx 取消上下文, source 源像素, profile 颜色配置,可为nil // 返回: image.Image 显示像素, error 变换或取消错误 func jpegDisplayImage(ctx context.Context, source image.Image, profile *pdfgo.ColorSpace) (image.Image, error) { @@ -265,6 +265,12 @@ func jpegDisplayImage(ctx context.Context, source image.Image, profile *pdfgo.Co return nil, fmt.Errorf("JPEG color image dimensions exceed capacity") } pixels := image.NewNRGBA64(bounds) + var intent pdfgo.Name + if profile != nil { + intent = profile.DefaultIntent() + } + var previous color.CMYK + var previousPixel color.NRGBA64 for y := bounds.Min.Y; y < bounds.Max.Y; y++ { for x := bounds.Min.X; x < bounds.Max.X; x++ { if (x-bounds.Min.X)&255 == 0 { @@ -283,12 +289,18 @@ func jpegDisplayImage(ctx context.Context, source image.Image, profile *pdfgo.Co }) continue } + if previousPixel.A != 0 && ink == previous { + pixels.SetNRGBA64(x, y, previousPixel) + continue + } values := [4]float64{float64(ink.C) / 255, float64(ink.M) / 255, float64(ink.Y) / 255, float64(ink.K) / 255} - rgb, err := profile.SRGB(values[:], profile.DefaultIntent()) + rgb, err := profile.SRGB(values[:], intent) if err != nil { return nil, err } - pixels.SetNRGBA64(x, y, color.NRGBA64{R: colorWord(rgb[0]), G: colorWord(rgb[1]), B: colorWord(rgb[2]), A: 65535}) + previous = ink + previousPixel = color.NRGBA64{R: colorWord(rgb[0]), G: colorWord(rgb[1]), B: colorWord(rgb[2]), A: 65535} + pixels.SetNRGBA64(x, y, previousPixel) } } return &colorImage{NRGBA64: pixels, source: source}, nil diff --git a/internal/base/image/tiff_profile.go b/internal/base/image/tiff_profile.go index 47cad48..22720a8 100644 --- a/internal/base/image/tiff_profile.go +++ b/internal/base/image/tiff_profile.go @@ -99,6 +99,7 @@ func applyImageColorProfile(ctx context.Context, source image.Image, profile *pd model := source.ColorModel() premultiplied := model == color.RGBAModel || model == color.RGBA64Model table := newTIFFProfileTable(source) + components, intent := profile.Components(), profile.DefaultIntent() result := image.NewNRGBA64(bounds) var previous [4]float64 var previousPixel color.NRGBA64 @@ -174,7 +175,7 @@ func applyImageColorProfile(ctx context.Context, source image.Image, profile *pd } } } - rgb, err := profile.SRGB(values[:profile.Components()], profile.DefaultIntent()) + rgb, err := profile.SRGB(values[:components], intent) if err != nil { return nil, err }