Compare commits

..
2 Commits
Author SHA1 Message Date
xiaoqidun e64575ec16 refactor(色彩管理): 优化图像色彩转换性能
build.yaml / build (push) Successful in 53s
2026-10-16 00:18:59 +08:00
xiaoqidun e1bf215e6a perf(色彩管理): 优化四色图像显示性能 2026-10-16 00:12:48 +08:00
2 changed files with 30 additions and 4 deletions

No files matched your search

+10 -3
View File
@@ -260,9 +260,6 @@ func jpegDisplayImage(ctx context.Context, source image.Image, profile *pdfgo.Co
} }
return source, nil return source, nil
} }
if profile == nil {
profile = &pdfgo.ColorSpace{Model: "DeviceCMYK"}
}
bounds := cmyk.Bounds() bounds := cmyk.Bounds()
if bounds.Dx() <= 0 || bounds.Dy() <= 0 || bounds.Dx() > math.MaxInt/8/bounds.Dy() { if bounds.Dx() <= 0 || bounds.Dy() <= 0 || bounds.Dx() > math.MaxInt/8/bounds.Dy() {
return nil, fmt.Errorf("JPEG color image dimensions exceed capacity") return nil, fmt.Errorf("JPEG color image dimensions exceed capacity")
@@ -276,6 +273,16 @@ func jpegDisplayImage(ctx context.Context, source image.Image, profile *pdfgo.Co
} }
} }
ink := cmyk.CMYKAt(x, y) ink := cmyk.CMYKAt(x, y)
if profile == nil {
white := 255 - int(ink.K)
pixels.SetNRGBA64(x, y, color.NRGBA64{
R: uint16(max(0, white-int(ink.C))) * 257,
G: uint16(max(0, white-int(ink.M))) * 257,
B: uint16(max(0, white-int(ink.Y))) * 257,
A: 65535,
})
continue
}
values := [4]float64{float64(ink.C) / 255, float64(ink.M) / 255, float64(ink.Y) / 255, float64(ink.K) / 255} 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[:], profile.DefaultIntent())
if err != nil { if err != nil {
+20 -1
View File
@@ -78,7 +78,7 @@ func applyTIFFColorProfile(ctx context.Context, source image.Image, profile *pdf
return applyImageColorProfile(ctx, source, profile, false) return applyImageColorProfile(ctx, source, profile, false)
} }
// applyImageColorProfile 按源配置转换显示像素,缺省传递函数在浮点域解码 // applyImageColorProfile 按源配置转换显示像素,精确复用连续同色结果
// 入参: ctx 取消上下文, source 源像素, profile 颜色空间, linearSRGB 是否先解码sRGB传递函数 // 入参: ctx 取消上下文, source 源像素, profile 颜色空间, linearSRGB 是否先解码sRGB传递函数
// 返回: image.Image 十六位显示图像, error 变换或取消错误 // 返回: image.Image 十六位显示图像, error 变换或取消错误
func applyImageColorProfile(ctx context.Context, source image.Image, profile *pdfgo.ColorSpace, linearSRGB bool) (image.Image, error) { func applyImageColorProfile(ctx context.Context, source image.Image, profile *pdfgo.ColorSpace, linearSRGB bool) (image.Image, error) {
@@ -100,7 +100,10 @@ func applyImageColorProfile(ctx context.Context, source image.Image, profile *pd
premultiplied := model == color.RGBAModel || model == color.RGBA64Model premultiplied := model == color.RGBAModel || model == color.RGBA64Model
table := newTIFFProfileTable(source) table := newTIFFProfileTable(source)
result := image.NewNRGBA64(bounds) result := image.NewNRGBA64(bounds)
var previous [4]float64
var previousPixel color.NRGBA64
for y := bounds.Min.Y; y < bounds.Max.Y; y++ { for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
misses := 0
for x := bounds.Min.X; x < bounds.Max.X; x++ { for x := bounds.Min.X; x < bounds.Max.X; x++ {
if (x-bounds.Min.X)&255 == 0 { if (x-bounds.Min.X)&255 == 0 {
if err := ctx.Err(); err != nil { if err := ctx.Err(); err != nil {
@@ -151,6 +154,17 @@ func applyImageColorProfile(ctx context.Context, source image.Image, profile *pd
alpha = pixel.A alpha = pixel.A
values = [4]float64{float64(pixel.R) / 65535, float64(pixel.G) / 65535, float64(pixel.B) / 65535} values = [4]float64{float64(pixel.R) / 65535, float64(pixel.G) / 65535, float64(pixel.B) / 65535}
} }
if misses < 32 {
if previousPixel.A != 0 && values == previous {
pixel := previousPixel
pixel.A = alpha
result.SetNRGBA64(x, y, pixel)
misses = 0
continue
}
previous = values
misses++
}
if linearSRGB { if linearSRGB {
for i := range 3 { for i := range 3 {
if values[i] <= 0.04045 { if values[i] <= 0.04045 {
@@ -168,6 +182,11 @@ func applyImageColorProfile(ctx context.Context, source image.Image, profile *pd
for i, value := range rgb { for i, value := range rgb {
channels[i] = uint16(math.Round(max(0, min(1, value)) * 65535)) channels[i] = uint16(math.Round(max(0, min(1, value)) * 65535))
} }
if misses < 32 {
previousPixel = color.NRGBA64{R: channels[0], G: channels[1], B: channels[2], A: 65535}
} else {
previousPixel.A = 0
}
if slot >= 0 { if slot >= 0 {
table[slot] = color.NRGBA64{R: channels[0], G: channels[1], B: channels[2], A: 65535} table[slot] = color.NRGBA64{R: channels[0], G: channels[1], B: channels[2], A: 65535}
} }