feat(优化性能): 继续优化性能
build.yaml / build (push) Successful in 34s

This commit is contained in:
2026-07-14 00:24:48 +08:00
parent 8a68014262
commit 08b801d351
2 changed files with 77 additions and 18 deletions
+22 -10
View File
@@ -30,16 +30,14 @@ import (
// 入参: data 图片数据
// 返回: image.Image 图片对象, string 图片格式, error 错误信息
func decodeImageData(data []byte) (image.Image, string, error) {
if _, format, err := image.DecodeConfig(bytes.NewReader(data)); err == nil {
switch format {
case "jpeg":
if img, err := canvasimage.NewJPEGImage(bytes.NewReader(data)); err == nil {
return img, format, nil
}
case "png":
if img, err := canvasimage.NewPNGImage(bytes.NewReader(data)); err == nil {
return img, format, nil
}
if isJPEGData(data) {
if img, err := canvasimage.NewJPEGImage(bytes.NewReader(data)); err == nil {
return img, "jpeg", nil
}
}
if isPNGData(data) {
if img, err := canvasimage.NewPNGImage(bytes.NewReader(data)); err == nil {
return img, "png", nil
}
}
img, format, err := image.Decode(bytes.NewReader(data))
@@ -52,6 +50,20 @@ func decodeImageData(data []byte) (image.Image, string, error) {
return nil, "", err
}
// isJPEGData 判断是否为JPEG图片数据
// 入参: data 图片数据
// 返回: bool 是否为JPEG图片数据
func isJPEGData(data []byte) bool {
return len(data) >= 2 && data[0] == 0xFF && data[1] == 0xD8
}
// isPNGData 判断是否为PNG图片数据
// 入参: data 图片数据
// 返回: bool 是否为PNG图片数据
func isPNGData(data []byte) bool {
return bytes.HasPrefix(data, []byte("\x89PNG\r\n\x1a\n"))
}
// decodeImageConfigData 解码图片尺寸
// 入参: data 图片数据
// 返回: image.Config 图片尺寸, string 图片格式, error 错误信息
+55 -8
View File
@@ -15,8 +15,10 @@
package ofdgo
import (
"bufio"
"image"
"image/color"
"io"
"github.com/tdewolff/canvas"
canvasimage "github.com/tdewolff/canvas/image"
@@ -32,11 +34,7 @@ func (r *Renderer) renderImage(ctx *canvas.Context, obj ImageObject, pageH float
if !ok {
return
}
imgData, err := r.Reader.ResData(resPath)
if err != nil {
return
}
img, _, err := decodeImageData(imgData)
img, err := r.decodeImageResource(resPath)
if err != nil {
return
}
@@ -78,6 +76,31 @@ func (r *Renderer) renderImage(ctx *canvas.Context, obj ImageObject, pageH float
ctx.RenderImage(img, ctx.CoordSystemView().Mul(ctx.View()).Mul(m))
}
// decodeImageResource 解码图片资源
// 入参: resPath 图片资源路径
// 返回: image.Image 图片对象, error 错误信息
func (r *Renderer) decodeImageResource(resPath string) (image.Image, error) {
rc, err := r.Reader.openFile(r.Reader.ResPath(resPath))
if err != nil {
return nil, err
}
defer rc.Close()
reader := bufio.NewReaderSize(rc, 8)
header, _ := reader.Peek(8)
if isJPEGData(header) {
return canvasimage.NewJPEGImage(reader)
}
if isPNGData(header) {
return canvasimage.NewPNGImage(reader)
}
data, err := io.ReadAll(reader)
if err != nil {
return nil, err
}
img, _, err := decodeImageData(data)
return img, err
}
// imageWithAlpha 合并图片透明度
// 入参: img 图片对象, alpha 对象透明度
// 返回: image.Image 合并后的图片对象
@@ -91,9 +114,10 @@ func imageWithAlpha(img image.Image, alpha *int) image.Image {
}
bounds := img.Bounds()
out := image.NewNRGBA(bounds)
source := imagePixelSource(img)
for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
for x := bounds.Min.X; x < bounds.Max.X; x++ {
c := color.NRGBAModel.Convert(img.At(x, y)).(color.NRGBA)
c := imageNRGBAAt(source, x, y)
c.A = uint8(int(c.A) * a / 255)
out.SetNRGBA(x, y, c)
}
@@ -116,14 +140,15 @@ func imageWithTransparentEdge(img image.Image) (image.Image, int) {
if src, ok := img.(*canvasimage.Image); ok && src.Mimetype == "image/jpeg" && src.Mask == nil {
return img, 0
}
if opaque, ok := img.(interface{ Opaque() bool }); ok && opaque.Opaque() {
source := imagePixelSource(img)
if opaque, ok := source.(interface{ Opaque() bool }); ok && opaque.Opaque() {
return img, 0
}
src := image.NewNRGBA(image.Rect(0, 0, w, h))
hasZero, hasVisible := false, false
for y := 0; y < h; y++ {
for x := 0; x < w; x++ {
c := color.NRGBAModel.Convert(img.At(bounds.Min.X+x, bounds.Min.Y+y)).(color.NRGBA)
c := imageNRGBAAt(source, bounds.Min.X+x, bounds.Min.Y+y)
src.SetNRGBA(x, y, c)
if c.A == 0 {
hasZero = true
@@ -162,6 +187,28 @@ func imageWithTransparentEdge(img image.Image) (image.Image, int) {
return out, 1
}
// imagePixelSource 获取图片像素源
// 入参: img 图片对象
// 返回: image.Image 图片像素源
func imagePixelSource(img image.Image) image.Image {
if src, ok := img.(*canvasimage.Image); ok {
if decoded, err := src.Image(); err == nil {
return decoded
}
}
return img
}
// imageNRGBAAt 获取图片NRGBA像素
// 入参: img 图片对象, x X坐标, y Y坐标
// 返回: color.NRGBA NRGBA像素
func imageNRGBAAt(img image.Image, x, y int) color.NRGBA {
if src, ok := img.(*image.NRGBA); ok {
return src.NRGBAAt(x, y)
}
return color.NRGBAModel.Convert(img.At(x, y)).(color.NRGBA)
}
// transparentEdgeColor 获取透明像素相邻的可见颜色
// 入参: img 图片对象, x X坐标, y Y坐标
// 返回: color.NRGBA 颜色, bool 是否存在