mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-10-30 01:27:26 +08:00
1 parent
478c18cb1f
commit
e5f34c6ea6
4 files changed
+44
-40
No files matched your search
@@ -9,7 +9,7 @@ require (
|
|||||||
github.com/tdewolff/canvas v0.0.0-20260923214215-09804640d00c
|
github.com/tdewolff/canvas v0.0.0-20260923214215-09804640d00c
|
||||||
github.com/xiaoqidun/j2kgo v0.0.0-20261011021706-cedb3037ff6e
|
github.com/xiaoqidun/j2kgo v0.0.0-20261011021706-cedb3037ff6e
|
||||||
github.com/xiaoqidun/jbig2 v1.1.4
|
github.com/xiaoqidun/jbig2 v1.1.4
|
||||||
github.com/xiaoqidun/pdfgo v0.0.0-20261011103616-6cafccc7f8f6
|
github.com/xiaoqidun/pdfgo v0.0.0-20261011112043-b424d0248fb2
|
||||||
golang.org/x/crypto v0.58.0
|
golang.org/x/crypto v0.58.0
|
||||||
golang.org/x/image v0.47.0
|
golang.org/x/image v0.47.0
|
||||||
golang.org/x/text v0.43.0
|
golang.org/x/text v0.43.0
|
||||||
|
|||||||
@@ -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/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 h1:LF6J1si4JY+TszTh9+m4KAg9/ba0JjfXoGtQTQC2S8c=
|
||||||
github.com/xiaoqidun/jbig2 v1.1.4/go.mod h1:9jromqVwMqlptUDEt6Yip8vqYA5I1YjhG7FgMl/Z2dA=
|
github.com/xiaoqidun/jbig2 v1.1.4/go.mod h1:9jromqVwMqlptUDEt6Yip8vqYA5I1YjhG7FgMl/Z2dA=
|
||||||
github.com/xiaoqidun/pdfgo v0.0.0-20261011103616-6cafccc7f8f6 h1:TW7d8qguwR6+WAxXw4ncAXdHTSrAgz6zjj7NmKbipyo=
|
github.com/xiaoqidun/pdfgo v0.0.0-20261011112043-b424d0248fb2 h1:bPq5g3O7XWOQAKG46vUYkVYXjFGiHhlvHhyjvlnJ9H8=
|
||||||
github.com/xiaoqidun/pdfgo v0.0.0-20261011103616-6cafccc7f8f6/go.mod h1:hkZn8gHOI94K0fE2ynbXaE8J5T0/jCvoTS/yroKgb+E=
|
github.com/xiaoqidun/pdfgo v0.0.0-20261011112043-b424d0248fb2/go.mod h1:hkZn8gHOI94K0fE2ynbXaE8J5T0/jCvoTS/yroKgb+E=
|
||||||
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
|
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
|
||||||
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
||||||
github.com/yuin/goldmark v1.8.5 h1:r6N5afV5qj/5S4UTch8agZHJ8UxNCMwX7WjkkJam2NA=
|
github.com/yuin/goldmark v1.8.5 h1:r6N5afV5qj/5S4UTch8agZHJ8UxNCMwX7WjkkJam2NA=
|
||||||
|
|||||||
+40
-36
@@ -123,10 +123,10 @@ func optimizeBMPResource(ctx context.Context, data []byte, options CompressionOp
|
|||||||
}
|
}
|
||||||
|
|
||||||
// optimizeRasterResource 编码已解码的资源图片,同步降采样后的像素密度,仅采用更小结果
|
// optimizeRasterResource 编码已解码的资源图片,同步降采样后的像素密度,仅采用更小结果
|
||||||
|
// 绝对密度在降采样后量化为PNG整数,避免原始有理数密度被二次舍入
|
||||||
// 入参: ctx 取消上下文, data 原编码, pixels 像素, options 压缩选项, size 像素需求, density 像素密度
|
// 入参: ctx 取消上下文, data 原编码, pixels 像素, options 压缩选项, size 像素需求, density 像素密度
|
||||||
// 返回: []byte 图片编码, error 编码或取消错误
|
// 返回: []byte 图片编码, error 编码或取消错误
|
||||||
func optimizeRasterResource(ctx context.Context, data []byte, pixels image.Image, options CompressionOptions, size image.Point, density rasterDensity) ([]byte, error) {
|
func optimizeRasterResource(ctx context.Context, data []byte, pixels image.Image, options CompressionOptions, size image.Point, density rasterDensity) ([]byte, error) {
|
||||||
width, height := pixels.Bounds().Dx(), pixels.Bounds().Dy()
|
|
||||||
var encoded bytes.Buffer
|
var encoded bytes.Buffer
|
||||||
limit := &outputCompressionBuffer{buffer: &encoded, limit: outputOptimizationBufferLimit}
|
limit := &outputCompressionBuffer{buffer: &encoded, limit: outputOptimizationBufferLimit}
|
||||||
if err := pdfgo.EncodePNG(ctx, limit, pixels); err != nil {
|
if err := pdfgo.EncodePNG(ctx, limit, pixels); err != nil {
|
||||||
@@ -135,43 +135,47 @@ func optimizeRasterResource(ctx context.Context, data []byte, pixels image.Image
|
|||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var candidate []byte
|
input := encoded.Bytes()
|
||||||
var err error
|
hasDensity := density.x != 0 || density.y != 0
|
||||||
if density.x == 0 && density.y == 0 {
|
if hasDensity && density.unit == 1 {
|
||||||
candidate, err = pdfgo.OptimizeImageResource(ctx, encoded.Bytes(), options, size)
|
var err error
|
||||||
} else {
|
input, err = pdfgo.OptimizeImageSize(ctx, input, options, size)
|
||||||
candidate, err = pdfgo.OptimizeImageSize(ctx, encoded.Bytes(), options, size)
|
if err != nil {
|
||||||
if err == nil {
|
return nil, err
|
||||||
config, _, configErr := image.DecodeConfig(bytes.NewReader(candidate))
|
|
||||||
if configErr != nil {
|
|
||||||
return nil, configErr
|
|
||||||
}
|
|
||||||
x := density.x * float64(config.Width) / float64(width)
|
|
||||||
y := density.y * float64(config.Height) / float64(height)
|
|
||||||
if density.unit == 0 {
|
|
||||||
factor := float64(math.MaxUint32) / max(x, y)
|
|
||||||
x, y = x*factor, y*factor
|
|
||||||
}
|
|
||||||
x, y = math.Round(x), math.Round(y)
|
|
||||||
if x > math.MaxUint32 || y > math.MaxUint32 || density.x > 0 && x < 1 || density.y > 0 && y < 1 {
|
|
||||||
return data, ctx.Err()
|
|
||||||
}
|
|
||||||
chunk := make([]byte, 21)
|
|
||||||
binary.BigEndian.PutUint32(chunk, 9)
|
|
||||||
copy(chunk[4:], "pHYs")
|
|
||||||
binary.BigEndian.PutUint32(chunk[8:], uint32(x))
|
|
||||||
binary.BigEndian.PutUint32(chunk[12:], uint32(y))
|
|
||||||
chunk[16] = density.unit
|
|
||||||
binary.BigEndian.PutUint32(chunk[17:], crc32.ChecksumIEEE(chunk[4:17]))
|
|
||||||
var output bytes.Buffer
|
|
||||||
writer := imageMetadataWriter{writer: &output, skip: 33, data: chunk}
|
|
||||||
if _, err = writer.Write(candidate); err == nil {
|
|
||||||
candidate = output.Bytes()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
config, _, err := image.DecodeConfig(bytes.NewReader(input))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
density.x *= float64(config.Width) / float64(pixels.Bounds().Dx())
|
||||||
|
density.y *= float64(config.Height) / float64(pixels.Bounds().Dy())
|
||||||
}
|
}
|
||||||
if err != nil {
|
if hasDensity {
|
||||||
return nil, err
|
x, y := math.Round(density.x), math.Round(density.y)
|
||||||
|
if x > math.MaxInt32 || y > math.MaxInt32 || density.x > 0 && x < 1 || density.y > 0 && y < 1 || len(input) > outputOptimizationBufferLimit-21 {
|
||||||
|
return data, ctx.Err()
|
||||||
|
}
|
||||||
|
chunk := make([]byte, 21)
|
||||||
|
binary.BigEndian.PutUint32(chunk, 9)
|
||||||
|
copy(chunk[4:], "pHYs")
|
||||||
|
binary.BigEndian.PutUint32(chunk[8:], uint32(x))
|
||||||
|
binary.BigEndian.PutUint32(chunk[12:], uint32(y))
|
||||||
|
chunk[16] = density.unit
|
||||||
|
binary.BigEndian.PutUint32(chunk[17:], crc32.ChecksumIEEE(chunk[4:17]))
|
||||||
|
var output bytes.Buffer
|
||||||
|
writer := imageMetadataWriter{writer: &output, skip: 33, data: chunk}
|
||||||
|
if _, err := writer.Write(input); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
input = output.Bytes()
|
||||||
|
}
|
||||||
|
candidate := input
|
||||||
|
if !hasDensity || density.unit == 0 {
|
||||||
|
var err error
|
||||||
|
candidate, err = pdfgo.OptimizeImageResource(ctx, input, options, size)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if err := ctx.Err(); err != nil {
|
if err := ctx.Err(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ func tiffCompressionDensity(data []byte, layout tiffImageLayout) (rasterDensity,
|
|||||||
}
|
}
|
||||||
density = rasterDensity{x: float64(x[0]) / float64(x[1]) * factor, y: float64(y[0]) / float64(y[1]) * factor, unit: 1}
|
density = rasterDensity{x: float64(x[0]) / float64(x[1]) * factor, y: float64(y[0]) / float64(y[1]) * factor, unit: 1}
|
||||||
}
|
}
|
||||||
if math.Round(density.x) < 1 || math.Round(density.y) < 1 || math.Round(density.x) > math.MaxUint32 || math.Round(density.y) > math.MaxUint32 {
|
if math.Round(density.x) < 1 || math.Round(density.y) < 1 || math.Round(density.x) > math.MaxInt32 || math.Round(density.y) > math.MaxInt32 {
|
||||||
return density, false
|
return density, false
|
||||||
}
|
}
|
||||||
if layout.orientation >= 5 {
|
if layout.orientation >= 5 {
|
||||||
|
|||||||
Reference in new issue
Block a user