From 34e17383f1168e1b369ccad6fa2b5aadb7c7595a Mon Sep 17 00:00:00 2001 From: xiaoqidun Date: Sun, 11 Oct 2026 19:34:17 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E5=9B=BE=E5=83=8F=E5=A4=84=E7=90=86):=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=BB=91=E7=99=BD=E5=8E=8B=E7=BC=A9=E4=B8=A2?= =?UTF-8?q?=E5=A4=B1=E9=99=84=E5=8A=A0=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 2 +- go.sum | 4 ++-- ofdgo_editor.go | 2 +- ofdgo_editor_image_binary.go | 32 +++++++++++++++++++++++++++++++- 4 files changed, 35 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index ce4e68b..c616a0a 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/tdewolff/canvas v0.0.0-20260923214215-09804640d00c github.com/xiaoqidun/j2kgo v0.0.0-20261011021706-cedb3037ff6e github.com/xiaoqidun/jbig2 v1.1.4 - github.com/xiaoqidun/pdfgo v0.0.0-20261011112043-b424d0248fb2 + github.com/xiaoqidun/pdfgo v0.0.0-20261011113302-5ef97798f3e9 golang.org/x/crypto v0.58.0 golang.org/x/image v0.47.0 golang.org/x/text v0.43.0 diff --git a/go.sum b/go.sum index e527a08..eb297cd 100644 --- a/go.sum +++ b/go.sum @@ -62,8 +62,8 @@ github.com/xiaoqidun/j2kgo v0.0.0-20261011021706-cedb3037ff6e h1:OuRcvG5g5AieBN3 github.com/xiaoqidun/j2kgo v0.0.0-20261011021706-cedb3037ff6e/go.mod h1:DCwAfuDzCDYqUiAlZ7BDwigTjaXw7o9L1FtEma/D1aA= github.com/xiaoqidun/jbig2 v1.1.4 h1:LF6J1si4JY+TszTh9+m4KAg9/ba0JjfXoGtQTQC2S8c= github.com/xiaoqidun/jbig2 v1.1.4/go.mod h1:9jromqVwMqlptUDEt6Yip8vqYA5I1YjhG7FgMl/Z2dA= -github.com/xiaoqidun/pdfgo v0.0.0-20261011112043-b424d0248fb2 h1:bPq5g3O7XWOQAKG46vUYkVYXjFGiHhlvHhyjvlnJ9H8= -github.com/xiaoqidun/pdfgo v0.0.0-20261011112043-b424d0248fb2/go.mod h1:hkZn8gHOI94K0fE2ynbXaE8J5T0/jCvoTS/yroKgb+E= +github.com/xiaoqidun/pdfgo v0.0.0-20261011113302-5ef97798f3e9 h1:ET5BMHDQ18Tr8sMUX7K8tw3FYMtBnl6pBYLYy0OI550= +github.com/xiaoqidun/pdfgo v0.0.0-20261011113302-5ef97798f3e9/go.mod h1:hkZn8gHOI94K0fE2ynbXaE8J5T0/jCvoTS/yroKgb+E= 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_editor.go b/ofdgo_editor.go index 94921bb..04e75c6 100644 --- a/ofdgo_editor.go +++ b/ofdgo_editor.go @@ -469,7 +469,7 @@ func (e *Editor) ResizePages(indexes []int, width, height float64) error { } // AddImage 注册PNG、JPEG、BMP、单页TIFF或JBIG2图片,重复资源复用标识,引用后写入文档 -// 不透明纯黑白PNG仅在无损JBIG2编码更小时转换,其他图片保留原始编码 +// 不透明纯黑白PNG仅在不含附加信息且无损JBIG2编码更小时转换,其他图片保留原始编码 // 入参: data 图片数据 // 返回: string 图片资源标识, error 错误信息 func (e *Editor) AddImage(data []byte) (string, error) { diff --git a/ofdgo_editor_image_binary.go b/ofdgo_editor_image_binary.go index d1c3095..70a6c34 100644 --- a/ofdgo_editor_image_binary.go +++ b/ofdgo_editor_image_binary.go @@ -34,10 +34,13 @@ type pngBinaryProbe struct { remaining int } -// editorBinaryImage 尝试纯黑白无损编码,不二值化,不改变透明度,无体积收益时保留原图 +// editorBinaryImage 尝试纯黑白无损编码,不改变透明度,带附加信息或无体积收益时保留原图 // 入参: data PNG图片数据, img 已解码像素,为nil时读取原图 // 返回: []byte 更小的JBIG2数据,不适用时为nil func editorBinaryImage(data []byte, img image.Image) []byte { + if !pngBinarySource(data) { + return nil + } if img == nil { if pngNonBinaryImage(data) { return nil @@ -55,6 +58,33 @@ func editorBinaryImage(data []byte, img image.Image) []byte { return output.Bytes() } +// pngBinarySource 检查PNG是否仅含图像与透明度数据,避免转为JBIG2时丢失附加信息 +// 入参: data PNG编码数据 +// 返回: bool 是否无需保留附加信息 +func pngBinarySource(data []byte) bool { + if len(data) < 33 || string(data[:8]) != "\x89PNG\r\n\x1a\n" { + return false + } + for pos := 8; pos < len(data); { + if len(data)-pos < 12 { + return false + } + length := uint64(binary.BigEndian.Uint32(data[pos:])) + 12 + if length > uint64(len(data)-pos) { + return false + } + switch string(data[pos+4 : pos+8]) { + case "IHDR", "PLTE", "IDAT", "tRNS": + case "IEND": + return length == 12 && pos+12 == len(data) + default: + return false + } + pos += int(length) + } + return false +} + // pngNonBinaryImage 检查PNG前部像素是否包含灰阶、彩色或透明度,仅用于排除黑白压缩 // 入参: data PNG图片数据 // 返回: bool 已发现非不透明黑白像素,无法判定时为false