mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-08-30 12:12:40 +08:00
+76
-10
@@ -18,16 +18,23 @@ import (
|
||||
"bytes"
|
||||
"image"
|
||||
"image/color"
|
||||
"image/draw"
|
||||
"math"
|
||||
|
||||
"github.com/tdewolff/canvas"
|
||||
"github.com/tdewolff/canvas/renderers/rasterizer"
|
||||
)
|
||||
|
||||
// renderStamp 渲染印章
|
||||
// 入参: ctx 画布上下文, s 印章对象, pageH 页面高度
|
||||
func (r *Renderer) renderStamp(ctx *canvas.Context, s Stamp, pageH float64) {
|
||||
x, y, w, h := s.Box.X, s.Box.Y, s.Box.W, s.Box.H
|
||||
screenY := pageH - (y + h)
|
||||
if s.Type == "ofd" && len(s.Data) > 0 {
|
||||
if s.Clip != nil {
|
||||
if img := r.renderOFDStampImage(s.Data); img != nil {
|
||||
r.renderStampImage(ctx, stampImageWithTransparentWhite(img), s, pageH)
|
||||
}
|
||||
return
|
||||
}
|
||||
reader, err := NewReader(bytes.NewReader(s.Data), int64(len(s.Data)))
|
||||
if err == nil {
|
||||
defer reader.Close()
|
||||
@@ -44,8 +51,8 @@ func (r *Renderer) renderStamp(ctx *canvas.Context, s Stamp, pageH float64) {
|
||||
continue
|
||||
}
|
||||
ctx.Push()
|
||||
ctx.Translate(x, screenY)
|
||||
ctx.Scale(w/sealBox.W, h/sealBox.H)
|
||||
ctx.Translate(s.Box.X, pageH-(s.Box.Y+s.Box.H))
|
||||
ctx.Scale(s.Box.W/sealBox.W, s.Box.H/sealBox.H)
|
||||
renderer.renderPageToContext(ctx, content, false)
|
||||
ctx.Pop()
|
||||
}
|
||||
@@ -56,17 +63,76 @@ func (r *Renderer) renderStamp(ctx *canvas.Context, s Stamp, pageH float64) {
|
||||
if len(s.Data) > 0 {
|
||||
img, _, err := decodeImageData(s.Data)
|
||||
if err == nil {
|
||||
img = stampImageWithTransparentWhite(img)
|
||||
ctx.Push()
|
||||
ctx.Translate(x, screenY)
|
||||
ctx.Scale(w/float64(img.Bounds().Dx()), h/float64(img.Bounds().Dy()))
|
||||
ctx.DrawImage(0, 0, img, canvas.DPMM(1.0))
|
||||
ctx.Pop()
|
||||
r.renderStampImage(ctx, stampImageWithTransparentWhite(img), s, pageH)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// renderOFDStampImage 渲染OFD印章图像
|
||||
// 入参: data OFD印章数据
|
||||
// 返回: image.Image 印章图像
|
||||
func (r *Renderer) renderOFDStampImage(data []byte) image.Image {
|
||||
reader, err := NewReader(bytes.NewReader(data), int64(len(data)))
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
defer reader.Close()
|
||||
doc, err := reader.Doc()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
renderer := r.childRenderer(reader)
|
||||
for _, pageRef := range doc.Pages.Page {
|
||||
content, err := reader.PageContent(pageRef)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
sealBox, err := renderer.GetPageBox(content)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
c := canvas.New(sealBox.W, sealBox.H)
|
||||
if err := renderer.renderPageToContext(canvas.NewContext(c), content, false); err != nil {
|
||||
continue
|
||||
}
|
||||
return rasterizer.Draw(c, canvas.DPMM(r.DPI/25.4), canvas.DefaultColorSpace)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// renderStampImage 渲染印章图像
|
||||
// 入参: ctx 画布上下文, img 印章图像, s 印章对象, pageH 页面高度
|
||||
func (r *Renderer) renderStampImage(ctx *canvas.Context, img image.Image, s Stamp, pageH float64) {
|
||||
box := s.Box
|
||||
if s.Clip != nil {
|
||||
img = clipStampImage(img, box, *s.Clip)
|
||||
box.X += s.Clip.X
|
||||
box.Y += s.Clip.Y
|
||||
box.W = s.Clip.W
|
||||
box.H = s.Clip.H
|
||||
}
|
||||
ctx.Push()
|
||||
ctx.Translate(box.X, pageH-(box.Y+box.H))
|
||||
ctx.Scale(box.W/float64(img.Bounds().Dx()), box.H/float64(img.Bounds().Dy()))
|
||||
ctx.DrawImage(0, 0, img, canvas.DPMM(1.0))
|
||||
ctx.Pop()
|
||||
}
|
||||
|
||||
// clipStampImage 裁剪印章图像
|
||||
// 入参: img 印章图像, box 印章区域, clip 裁剪区域
|
||||
// 返回: image.Image 裁剪后的印章图像
|
||||
func clipStampImage(img image.Image, box, clip Box) image.Image {
|
||||
bounds := img.Bounds()
|
||||
x0 := int(math.Floor(clip.X / box.W * float64(bounds.Dx())))
|
||||
y0 := int(math.Floor(clip.Y / box.H * float64(bounds.Dy())))
|
||||
x1 := int(math.Ceil((clip.X + clip.W) / box.W * float64(bounds.Dx())))
|
||||
y1 := int(math.Ceil((clip.Y + clip.H) / box.H * float64(bounds.Dy())))
|
||||
out := image.NewNRGBA(image.Rect(0, 0, x1-x0, y1-y0))
|
||||
draw.Draw(out, out.Bounds(), img, image.Pt(bounds.Min.X+x0, bounds.Min.Y+y0), draw.Src)
|
||||
return out
|
||||
}
|
||||
|
||||
// stampImageWithTransparentWhite 处理印章图片白色底色
|
||||
// 入参: img 印章图片对象
|
||||
// 返回: image.Image 处理后的印章图片对象
|
||||
|
||||
Reference in New Issue
Block a user