From 9c5ce1d66f29fe96d308c514e1e85a2c1ede387c Mon Sep 17 00:00:00 2001 From: xiaoqidun Date: Thu, 1 Oct 2026 09:05:04 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E8=BD=AC=E6=8D=A2=E8=83=BD=E5=8A=9B):=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=9B=BE=E5=83=8F=E8=BD=AC=E6=8D=A2=E4=B8=8E?= =?UTF-8?q?=E6=97=A5=E6=9C=9F=E4=BF=9D=E7=95=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 4 +-- go.sum | 4 +-- ofdgo_pdf_object.go | 63 +++++++++++++++++++++++++++++---------------- 3 files changed, 45 insertions(+), 26 deletions(-) diff --git a/go.mod b/go.mod index edede07..8e618ac 100644 --- a/go.mod +++ b/go.mod @@ -6,10 +6,11 @@ require ( github.com/emmansun/gmsm v0.44.1 github.com/go-fonts/latin-modern v0.3.3 github.com/go-text/typesetting v0.3.5 + github.com/mububoki/jpeg2000 v1.0.0 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-20260930154408-27ca213a4f2a + github.com/xiaoqidun/pdfgo v0.0.0-20261001010247-f9839c149d47 golang.org/x/crypto v0.57.0 golang.org/x/image v0.46.0 golang.org/x/text v0.42.0 @@ -26,7 +27,6 @@ require ( github.com/benoitkugler/textlayout v0.3.2 // indirect github.com/benoitkugler/textprocessing v0.0.6 // indirect github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect - github.com/mububoki/jpeg2000 v1.0.0 // indirect github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef // indirect github.com/srwiley/scanx v0.0.0-20190309010443-e94503791388 // indirect github.com/tdewolff/minify/v2 v2.24.17 // indirect diff --git a/go.sum b/go.sum index 1020b82..a65517f 100644 --- a/go.sum +++ b/go.sum @@ -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-20260930154408-27ca213a4f2a h1:uoc2uT3bVXxEIzFUj8sLO1FloPi3JTcqLHpNztQB+qs= -github.com/xiaoqidun/pdfgo v0.0.0-20260930154408-27ca213a4f2a/go.mod h1:4Pf0JO0BEf1uzRY+uZjlMjN/OPn3PYa0YMi6cqPPTLQ= +github.com/xiaoqidun/pdfgo v0.0.0-20261001010247-f9839c149d47 h1:K81kklR5kcVJzV7EWUNCpQJHxw1v2vLI7eegfOs0xbI= +github.com/xiaoqidun/pdfgo v0.0.0-20261001010247-f9839c149d47/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= diff --git a/ofdgo_pdf_object.go b/ofdgo_pdf_object.go index e102564..22417a6 100644 --- a/ofdgo_pdf_object.go +++ b/ofdgo_pdf_object.go @@ -38,6 +38,39 @@ type pdfImageKey struct { intent pdfgo.Name } +// pdfStencilImage 按当前填充色读取模板图像,不分配整幅彩色样本 +type pdfStencilImage struct { + source image.Image + fill color.NRGBA64 +} + +// ColorModel 保留填充色和模板的有效采样精度 +// 返回: color.Model 非预乘颜色模型 +func (s *pdfStencilImage) ColorModel() color.Model { + model := s.source.ColorModel() + if s.fill.R%257 == 0 && s.fill.G%257 == 0 && s.fill.B%257 == 0 && (model == color.GrayModel || model == color.NRGBAModel || model == color.RGBAModel) { + return color.NRGBAModel + } + return color.NRGBA64Model +} + +// Bounds 返回模板图像的采样边界 +// 返回: image.Rectangle 图像边界 +func (s *pdfStencilImage) Bounds() image.Rectangle { return s.source.Bounds() } + +// At 以模板灰度计算填充覆盖率,不重复变换颜色 +// 入参: x 横向坐标, y 纵向坐标 +// 返回: color.Color 非预乘颜色 +func (s *pdfStencilImage) At(x, y int) color.Color { + if !image.Pt(x, y).In(s.Bounds()) { + return color.NRGBA64{} + } + gray, _, _, _ := s.source.At(x, y).RGBA() + pixel := s.fill + pixel.A = uint16(65535 - gray) + return pixel +} + // image 转换图像样本,不将整页或其他对象栅格化 // 入参: mark PDF图像绘制信息 // 返回: error 错误信息 @@ -88,33 +121,19 @@ func (p *pdfImporter) image(mark pdfgo.ImageMark) error { } if source.ImageMask { fill := mark.Style.Fill.RGB + if values := mark.Style.Fill.CMYK; values != nil { + space := &pdfgo.ColorSpace{Model: "DeviceCMYK"} + fill, err = space.RGB(values[:], mark.Style.RenderingIntent) + if err != nil { + return err + } + } tint := color.NRGBA64{ R: uint16(math.Round(fill[0] * 65535)), G: uint16(math.Round(fill[1] * 65535)), B: uint16(math.Round(fill[2] * 65535)), } - if mark.Style.Fill.CMYK != nil { - components := *mark.Style.Fill.CMYK - tint = color.NRGBA64Model.Convert(color.CMYK{ - C: uint8(math.Round(components[0] * 255)), - M: uint8(math.Round(components[1] * 255)), - Y: uint8(math.Round(components[2] * 255)), - K: uint8(math.Round(components[3] * 255)), - }).(color.NRGBA64) - } - stencil := image.NewNRGBA64(image.Rect(0, 0, source.Width, source.Height)) - for y := 0; y < source.Height; y++ { - for x := 0; x < source.Width; x++ { - gray, _, _, _ := decoded.At(x, y).RGBA() - stencil.SetNRGBA64(x, y, color.NRGBA64{ - R: tint.R, - G: tint.G, - B: tint.B, - A: uint16(65535 - gray), - }) - } - } - decoded = stencil + decoded = &pdfStencilImage{source: decoded, fill: tint} } var encoded bytes.Buffer if len(jbig2Original) != 0 {