mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-10-29 16:59:27 +08:00
1 parent
3d37b0d510
commit
5d1fd593cd
4 files changed
+91
-18
No files matched your search
+15
-5
@@ -19,6 +19,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
|
"io"
|
||||||
"math"
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -90,7 +91,7 @@ func (e *Editor) ImportImages(ctx context.Context, sources []ImagePageSource, at
|
|||||||
if err := ctx.Err(); err != nil {
|
if err := ctx.Err(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
page, err := e.addImagePage(data, options)
|
page, err := e.addImagePage(ctx, data, options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("image %q: %w", source.Name, err)
|
return fmt.Errorf("image %q: %w", source.Name, err)
|
||||||
}
|
}
|
||||||
@@ -107,9 +108,12 @@ func (e *Editor) ImportImages(ctx context.Context, sources []ImagePageSource, at
|
|||||||
}
|
}
|
||||||
|
|
||||||
// addImagePage 保留原图并按方向、物理尺寸与纸张选项建页
|
// addImagePage 保留原图并按方向、物理尺寸与纸张选项建页
|
||||||
// 入参: data 图片数据, options 建页选项
|
// 入参: ctx 取消上下文, data 图片数据, options 建页选项
|
||||||
// 返回: int 从0开始的页面索引, error 错误信息
|
// 返回: int 从0开始的页面索引, error 错误信息
|
||||||
func (e *Editor) addImagePage(data []byte, options ImagePageOptions) (int, error) {
|
func (e *Editor) addImagePage(ctx context.Context, data []byte, options ImagePageOptions) (int, error) {
|
||||||
|
if err := ctx.Err(); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
config, format, err := decodeImageConfigData(data)
|
config, format, err := decodeImageConfigData(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@@ -119,9 +123,12 @@ func (e *Editor) addImagePage(data []byte, options ImagePageOptions) (int, error
|
|||||||
}
|
}
|
||||||
var decoded image.Image
|
var decoded image.Image
|
||||||
if format == "bmp" || format == "tiff" {
|
if format == "bmp" || format == "tiff" {
|
||||||
decoded, _, err = decodeImageData(data)
|
decoded, _, err = decodeImageDataContext(ctx, data)
|
||||||
} else {
|
} else {
|
||||||
decoded, _, err = image.Decode(bytes.NewReader(data))
|
decoded, _, err = image.Decode(imageInput{ReadCloser: io.NopCloser(bytes.NewReader(data)), context: ctx})
|
||||||
|
}
|
||||||
|
if cancelErr := ctx.Err(); cancelErr != nil {
|
||||||
|
return 0, cancelErr
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@@ -144,6 +151,9 @@ func (e *Editor) addImagePage(data []byte, options ImagePageOptions) (int, error
|
|||||||
if !finite(w) || !finite(h) || w <= 0 || h <= 0 {
|
if !finite(w) || !finite(h) || w <= 0 || h <= 0 {
|
||||||
return 0, fmt.Errorf("invalid image page dimensions")
|
return 0, fmt.Errorf("invalid image page dimensions")
|
||||||
}
|
}
|
||||||
|
if err := ctx.Err(); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
resource, err := e.addImage(data, config, format, decoded)
|
resource, err := e.addImage(data, config, format, decoded)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ package ofdgo
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
"math"
|
"math"
|
||||||
@@ -158,20 +159,27 @@ func (c *semanticCompiler) drawStampContent(stamp Stamp) error {
|
|||||||
if c.textOnly || c.measure || len(stamp.Data) == 0 {
|
if c.textOnly || c.measure || len(stamp.Data) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
ctx := c.renderer.pageContext
|
||||||
|
if ctx == nil {
|
||||||
|
ctx = context.Background()
|
||||||
|
}
|
||||||
|
if err := ctx.Err(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if stamp.Type == "ofd" {
|
if stamp.Type == "ofd" {
|
||||||
reader, err := NewReader(bytes.NewReader(stamp.Data), int64(len(stamp.Data)))
|
reader, err := NewReader(bytes.NewReader(stamp.Data), int64(len(stamp.Data)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer reader.Close()
|
defer reader.Close()
|
||||||
document, err := reader.Doc()
|
document, err := reader.DocContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
renderer := c.renderer.childRenderer(reader)
|
renderer := c.renderer.childRenderer(reader)
|
||||||
renderer.TransparentBackground = true
|
renderer.TransparentBackground = true
|
||||||
for _, reference := range document.Pages.Page {
|
for _, reference := range document.Pages.Page {
|
||||||
content, err := reader.PageContent(reference)
|
content, err := reader.PageContentContext(ctx, reference)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -218,7 +226,7 @@ func (c *semanticCompiler) drawStampContent(stamp Stamp) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
img, _, err := decodeImageData(stamp.Data)
|
img, _, err := decodeImageDataContext(ctx, stamp.Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
+27
-5
@@ -15,6 +15,7 @@
|
|||||||
package ofdgo
|
package ofdgo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"fmt"
|
"fmt"
|
||||||
"slices"
|
"slices"
|
||||||
@@ -62,6 +63,13 @@ func (c *semanticCompiler) sharedStamp(stamp Stamp, compile func(*semanticCompil
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
r := c.renderer
|
r := c.renderer
|
||||||
|
ctx := r.pageContext
|
||||||
|
if ctx == nil {
|
||||||
|
ctx = context.Background()
|
||||||
|
}
|
||||||
|
if err := ctx.Err(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
state, _ := r.backendStates[stampContentStateKey{}].(*stampContentState)
|
state, _ := r.backendStates[stampContentStateKey{}].(*stampContentState)
|
||||||
config := r.backends
|
config := r.backends
|
||||||
if state == nil || !sameBackend(state.config.Fonts, config.Fonts) || !sameBackend(state.config.Geometry, config.Geometry) ||
|
if state == nil || !sameBackend(state.config.Fonts, config.Fonts) || !sameBackend(state.config.Geometry, config.Geometry) ||
|
||||||
@@ -80,17 +88,31 @@ func (c *semanticCompiler) sharedStamp(stamp Stamp, compile func(*semanticCompil
|
|||||||
local.Box.X, local.Box.Y = 0, 0
|
local.Box.X, local.Box.Y = 0, 0
|
||||||
page := &RasterPage{Width: c.page.Width, Height: c.page.Height, DPI: c.page.DPI}
|
page := &RasterPage{Width: c.page.Width, Height: c.page.Height, DPI: c.page.DPI}
|
||||||
child := &semanticCompiler{renderer: r, geometry: c.geometry, page: page, patterns: c.patterns}
|
child := &semanticCompiler{renderer: r, geometry: c.geometry, page: page, patterns: c.patterns}
|
||||||
if err := compile(child, local); err != nil {
|
err := compile(child, local)
|
||||||
|
if cancelErr := ctx.Err(); cancelErr != nil {
|
||||||
|
return cancelErr
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
commands = page.Commands
|
commands = page.Commands
|
||||||
cost := 0
|
cost := 0
|
||||||
for _, command := range commands {
|
for _, command := range commands {
|
||||||
cost += rasterCommandCost(command)
|
part := rasterCommandCost(command)
|
||||||
if command.Image != nil {
|
if part < 0 || part > state.cache.limit-cost {
|
||||||
bounds := command.Image.Bounds()
|
cost = state.cache.limit + 1
|
||||||
cost += bounds.Dx() * bounds.Dy() * 4
|
break
|
||||||
}
|
}
|
||||||
|
cost += part
|
||||||
|
if command.Image != nil {
|
||||||
|
cost += imageResourceCost(command.Image, state.cache.limit-cost)
|
||||||
|
}
|
||||||
|
if cost > state.cache.limit {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := ctx.Err(); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
state.cache.put(key, commands, cost)
|
state.cache.put(key, commands, cost)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ package ofdgo
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"image"
|
"image"
|
||||||
|
|
||||||
"github.com/tdewolff/canvas"
|
"github.com/tdewolff/canvas"
|
||||||
@@ -27,6 +28,19 @@ func (r *Renderer) renderStamp(ctx *canvas.Context, s Stamp, pageH float64) {
|
|||||||
if r.textOnly {
|
if r.textOnly {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
pageContext := r.pageContext
|
||||||
|
if pageContext == nil {
|
||||||
|
pageContext = context.Background()
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if err := pageContext.Err(); err != nil {
|
||||||
|
r.renderError = err
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
if err := pageContext.Err(); err != nil {
|
||||||
|
r.renderError = err
|
||||||
|
return
|
||||||
|
}
|
||||||
if s.Type == "ofd" && len(s.Data) > 0 {
|
if s.Type == "ofd" && len(s.Data) > 0 {
|
||||||
if s.Clip != nil {
|
if s.Clip != nil {
|
||||||
if img := r.renderOFDStampImage(s.Data); img != nil {
|
if img := r.renderOFDStampImage(s.Data); img != nil {
|
||||||
@@ -37,12 +51,15 @@ func (r *Renderer) renderStamp(ctx *canvas.Context, s Stamp, pageH float64) {
|
|||||||
reader, err := NewReader(bytes.NewReader(s.Data), int64(len(s.Data)))
|
reader, err := NewReader(bytes.NewReader(s.Data), int64(len(s.Data)))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
defer reader.Close()
|
defer reader.Close()
|
||||||
doc, err := reader.Doc()
|
doc, err := reader.DocContext(pageContext)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
renderer := r.childRenderer(reader)
|
renderer := r.childRenderer(reader)
|
||||||
for _, pageRef := range doc.Pages.Page {
|
for _, pageRef := range doc.Pages.Page {
|
||||||
content, err := reader.PageContent(pageRef)
|
content, err := reader.PageContentContext(pageContext, pageRef)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if pageContext.Err() != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
sealBox, err := renderer.GetPageBox(content)
|
sealBox, err := renderer.GetPageBox(content)
|
||||||
@@ -64,7 +81,7 @@ func (r *Renderer) renderStamp(ctx *canvas.Context, s Stamp, pageH float64) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(s.Data) > 0 {
|
if len(s.Data) > 0 {
|
||||||
img, _, err := decodeImageData(s.Data)
|
img, _, err := decodeImageDataContext(pageContext, s.Data)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if r.decodeImages {
|
if r.decodeImages {
|
||||||
img = imagePixelSource(img)
|
img = imagePixelSource(img)
|
||||||
@@ -79,12 +96,25 @@ func (r *Renderer) renderStamp(ctx *canvas.Context, s Stamp, pageH float64) {
|
|||||||
// 入参: data OFD印章数据
|
// 入参: data OFD印章数据
|
||||||
// 返回: image.Image 印章图像
|
// 返回: image.Image 印章图像
|
||||||
func (r *Renderer) renderOFDStampImage(data []byte) image.Image {
|
func (r *Renderer) renderOFDStampImage(data []byte) image.Image {
|
||||||
|
ctx := r.pageContext
|
||||||
|
if ctx == nil {
|
||||||
|
ctx = context.Background()
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if err := ctx.Err(); err != nil {
|
||||||
|
r.renderError = err
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
if err := ctx.Err(); err != nil {
|
||||||
|
r.renderError = err
|
||||||
|
return nil
|
||||||
|
}
|
||||||
reader, err := NewReader(bytes.NewReader(data), int64(len(data)))
|
reader, err := NewReader(bytes.NewReader(data), int64(len(data)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
defer reader.Close()
|
defer reader.Close()
|
||||||
doc, err := reader.Doc()
|
doc, err := reader.DocContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -92,8 +122,11 @@ func (r *Renderer) renderOFDStampImage(data []byte) image.Image {
|
|||||||
renderer.decodeImages = true
|
renderer.decodeImages = true
|
||||||
renderer.TransparentBackground = true
|
renderer.TransparentBackground = true
|
||||||
for _, pageRef := range doc.Pages.Page {
|
for _, pageRef := range doc.Pages.Page {
|
||||||
content, err := reader.PageContent(pageRef)
|
content, err := reader.PageContentContext(ctx, pageRef)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if ctx.Err() != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
img, err := renderer.RenderToImage(content)
|
img, err := renderer.RenderToImage(content)
|
||||||
|
|||||||
Reference in new issue
Block a user