feat(字体图像): 优化字体图像并修正签章裁剪
build.yaml / build (push) Successful in 3m41s

This commit is contained in:
xiaoqidun committed 2026-10-12 23:04:11 +08:00
1 parent 5d1fd593cd
commit f8263f798f
21 files changed
+1029 -336

No files matched your search

+32 -4
View File
@@ -15,8 +15,11 @@
package ofdgo
import (
"bytes"
"context"
"crypto/sha256"
"image"
"io"
"runtime"
"sync"
)
@@ -24,6 +27,9 @@ import (
// outputImageBatchLimit 限制并行批次持有的原始编码,超限图片单独处理
const outputImageBatchLimit = 16 << 20
// outputImageWorkingSetLimit 限制并行批次的像素工作量估算,超限图片单独处理
const outputImageWorkingSetLimit = 64 << 20
// outputImageJob 保存独立图片任务,不访问编辑文档或调用进度回调
type outputImageJob struct {
key outputImageKey
@@ -63,13 +69,13 @@ func (e *Editor) prepareOutputImages(keys []string, load func(string) ([]byte, e
return nil
}
batch := make([]outputImageJob, 0, workers)
size := 0
size, workingSet := 0, 0
run := func() error {
if err := e.runOutputImages(batch, results); err != nil {
return err
}
clear(batch)
batch, size = batch[:0], 0
batch, size, workingSet = batch[:0], 0, 0
return nil
}
for _, key := range keys {
@@ -101,14 +107,16 @@ func (e *Editor) prepareOutputImages(keys []string, load func(string) ([]byte, e
if duplicate {
continue
}
if len(batch) != 0 && len(data) > outputImageBatchLimit-size {
cost := outputImageWorkingSet(e.output.ctx, data)
if len(batch) != 0 && (len(data) > outputImageBatchLimit-size || cost > outputImageWorkingSetLimit-workingSet) {
if err := run(); err != nil {
return err
}
}
batch = append(batch, outputImageJob{key: cacheKey, data: data})
size += len(data)
if len(batch) == workers || size >= outputImageBatchLimit {
workingSet += cost
if len(batch) == workers || size >= outputImageBatchLimit || workingSet >= outputImageWorkingSetLimit {
if err := run(); err != nil {
return err
}
@@ -117,6 +125,26 @@ func (e *Editor) prepareOutputImages(keys []string, load func(string) ([]byte, e
return run()
}
// outputImageWorkingSet 按原图尺寸估算解码和重采样缓冲,不以降采样目标代替原图
// 按两份16位RGBA像素缓冲分批,不代表实际内存上限;格式或尺寸不明时单独处理
// 入参: ctx 取消上下文, data 原始图像编码
// 返回: int 编码及像素缓冲的估算字节数,上限为单批预算
func outputImageWorkingSet(ctx context.Context, data []byte) int {
if len(data) >= outputImageWorkingSetLimit {
return outputImageWorkingSetLimit
}
input := imageInput{ReadCloser: io.NopCloser(bytes.NewReader(data)), context: ctx}
config, _, err := decodeImageConfig(input)
if err != nil || config.Width <= 0 || config.Height <= 0 {
return outputImageWorkingSetLimit
}
available := outputImageWorkingSetLimit - len(data)
if config.Width > available/16/config.Height {
return outputImageWorkingSetLimit
}
return len(data) + config.Width*config.Height*16
}
// runOutputImages 等待整批结束后记录更小候选,失败图片保留原始编码
// 入参: jobs 独占图片任务, results 本次写出的候选缓存
// 返回: error 取消错误