feat(转换能力): 优化色料转换采样
build.yaml / build (push) Successful in 52s

This commit is contained in:
xiaoqidun committed 2026-10-08 12:59:00 +08:00
1 parent 0351dd54f5
commit 245fffed84
5 files changed
+47 -30

No files matched your search

+1 -1
View File
@@ -10,7 +10,7 @@ require (
github.com/tdewolff/canvas v0.0.0-20260923214215-09804640d00c
github.com/tdewolff/font v0.0.0-20260913163313-54f98bb59ee6
github.com/xiaoqidun/jbig2 v1.1.1
github.com/xiaoqidun/pdfgo v0.0.0-20261008021024-e8f1cc0a7ad9
github.com/xiaoqidun/pdfgo v0.0.0-20261008045044-ada80114c916
golang.org/x/crypto v0.57.0
golang.org/x/image v0.46.0
golang.org/x/text v0.42.0
+2 -2
View File
@@ -62,8 +62,8 @@ github.com/tdewolff/test v1.0.12 h1:7F21DqIajswxuche0geHdrUZRCWE4oko4b7bcmkkrxk=
github.com/tdewolff/test v1.0.12/go.mod h1:XPuWBzvdUzhCuxWO1ojpXsyzsA5bFoS3tO/Q3kFuTG8=
github.com/xiaoqidun/jbig2 v1.1.1 h1:SjliS9ZO0e9HX5oYUfBuXrfFsXhWricrSz+XY4zORDI=
github.com/xiaoqidun/jbig2 v1.1.1/go.mod h1:8QonVWtENmh2kc6l+leqeGl7psb79DWlHDkCpdChjfQ=
github.com/xiaoqidun/pdfgo v0.0.0-20261008021024-e8f1cc0a7ad9 h1:aHEEZYzIL7cCLW9IXMlBC+LyCxkYrge3Zw/GfioDT2I=
github.com/xiaoqidun/pdfgo v0.0.0-20261008021024-e8f1cc0a7ad9/go.mod h1:4Pf0JO0BEf1uzRY+uZjlMjN/OPn3PYa0YMi6cqPPTLQ=
github.com/xiaoqidun/pdfgo v0.0.0-20261008045044-ada80114c916 h1:SwXbZ6zLtTCxMeV7A5GBSxgNhyVfdzWLhPh38IdkVTc=
github.com/xiaoqidun/pdfgo v0.0.0-20261008045044-ada80114c916/go.mod h1:4Pf0JO0BEf1uzRY+uZjlMjN/OPn3PYa0YMi6cqPPTLQ=
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
github.com/yuin/goldmark v1.8.5 h1:r6N5afV5qj/5S4UTch8agZHJ8UxNCMwX7WjkkJam2NA=
+11 -16
View File
@@ -789,8 +789,12 @@ func (c *pdfCompositor) imageColor(mark *pdfgo.ImageMark, point pdfgo.Point, spa
if point.X < 0 || point.X > 1 || point.Y < 0 || point.Y > 1 {
return [4]float64{}, 0, nil
}
process, err := c.cache.imageProcess(c.importer, mark.Image, space, c.softMask)
if err != nil {
return [4]float64{}, 0, err
}
source := c.cache.images[mark.Image]
if source == nil {
if process == nil && source == nil {
var err error
source, err = mark.Image.DecodeComponentsViewContext(c.importer.ctx)
if err != nil {
@@ -798,22 +802,13 @@ func (c *pdfCompositor) imageColor(mark *pdfgo.ImageMark, point pdfgo.Point, spa
}
c.cache.images[mark.Image] = source
}
x, y := point.X*float64(source.Rect.Dx())-.5, (1-point.Y)*float64(source.Rect.Dy())-.5
key := pdfImageProcessKey{image: mark.Image, space: space, softMask: c.softMask}
process, prepared := c.cache.imageProcesses[key]
if !prepared {
var err error
process, err = source.PrepareProcess(&pdfgo.ColorantDevice{Space: space}, space, c.softMask)
if err != nil {
return [4]float64{}, 0, err
}
if c.cache.imageProcesses == nil {
c.cache.imageProcesses = make(map[pdfImageProcessKey]*pdfgo.ImageProcess)
}
c.cache.imageProcesses[key] = process
bounds := process.Bounds()
if process == nil {
bounds = source.Rect
}
x, y := point.X*float64(bounds.Dx())-.5, (1-point.Y)*float64(bounds.Dy())-.5
sample := func(x, y int) ([4]float64, float64) {
x, y = source.Rect.Min.X+max(0, min(source.Rect.Dx()-1, x)), source.Rect.Min.Y+max(0, min(source.Rect.Dy()-1, y))
x, y = bounds.Min.X+max(0, min(bounds.Dx()-1, x)), bounds.Min.Y+max(0, min(bounds.Dy()-1, y))
if process != nil {
return process.ValuesAt(x, y)
}
@@ -862,7 +857,7 @@ func (c *pdfCompositor) imageColor(mark *pdfgo.ImageMark, point pdfgo.Point, spa
if process != nil || space.Equal(source.Space) {
return values, alpha, nil
}
values, err := space.ConvertWith(values[:source.Space.Components()], source.Space, mark.Style.RenderingIntent, mark.Style.ColorConversion)
values, err = space.ConvertWith(values[:source.Space.Components()], source.Space, mark.Style.RenderingIntent, mark.Style.ColorConversion)
return values, alpha, err
}
+6 -1
View File
@@ -246,9 +246,13 @@ func (p *pdfImporter) directCompositeNode(node pdfCompositeNode, space *pdfgo.Co
}
if space.Model == "DeviceCMYK" && style.ColorConversion != (pdfgo.ColorConversion{}) {
if node.image != nil && !node.image.Image.ImageMask {
_, native, err := pdfImageProcessColorants(node.image.Image)
if err != nil {
return false, err
}
if !native {
source := p.compositingCache().images[node.image.Image]
if source == nil {
var err error
source, err = node.image.Image.DecodeComponentsViewContext(p.ctx)
if err != nil {
return false, err
@@ -258,6 +262,7 @@ func (p *pdfImporter) directCompositeNode(node pdfCompositeNode, space *pdfgo.Co
if source.Space.Model == "DeviceRGB" && source.Space.Device() {
return false, nil
}
}
} else {
for i, paint := range [2]pdfgo.Paint{style.Fill, style.Stroke} {
if i == 0 && !fill || i == 1 && !stroke || paint.None || paint.Tiling != nil {
+27 -10
View File
@@ -53,17 +53,8 @@ func (p *pdfImporter) imageProcessModel(source *pdfgo.Image) (pdfgo.Name, error)
// 返回: image.Image 只读图像, error 解码或分量映射错误
func (p *pdfImporter) imageProcess(source *pdfgo.Image, model pdfgo.Name) (image.Image, error) {
cache := p.compositingCache()
components := cache.images[source]
if components == nil {
var err error
components, err = source.DecodeComponentsViewContext(p.ctx)
if err != nil {
return nil, err
}
cache.images[source] = components
}
space := &pdfgo.ColorSpace{Model: model}
process, err := components.PrepareProcess(&pdfgo.ColorantDevice{Space: space}, space, false)
process, err := cache.imageProcess(p, source, space, false)
if err != nil {
return nil, err
}
@@ -73,6 +64,32 @@ func (p *pdfImporter) imageProcess(source *pdfgo.Image, model pdfgo.Name) (image
return &pdfNativeImage{source: process, space: space}, nil
}
// imageProcess 复用同组原生采样,仅在需要备用颜色时保留完整分量
// 入参: importer 导入器, source 源图像, space 组混合空间, softMask 是否用于软蒙版
// 返回: *pdfgo.ImageProcess 原生采样,需要备用色时为nil, error 解码或布局错误
func (c *pdfCompositeCache) imageProcess(importer *pdfImporter, source *pdfgo.Image, space *pdfgo.ColorSpace, softMask bool) (*pdfgo.ImageProcess, error) {
key := pdfImageProcessKey{image: source, space: space, softMask: softMask}
if process, found := c.imageProcesses[key]; found {
return process, nil
}
device := &pdfgo.ColorantDevice{Space: space}
var process *pdfgo.ImageProcess
var err error
if components := c.images[source]; components != nil {
process, err = components.PrepareProcess(device, space, softMask)
} else {
process, err = source.DecodeProcessContext(importer.ctx, device, space, softMask)
}
if err != nil {
return nil, err
}
if c.imageProcesses == nil {
c.imageProcesses = make(map[pdfImageProcessKey]*pdfgo.ImageProcess)
}
c.imageProcesses[key] = process
return process, nil
}
// ColorModel 保留16位原生分量与源透明度
// 返回: color.Model 非预乘颜色模型
func (s *pdfNativeImage) ColorModel() color.Model { return color.NRGBA64Model }