-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathImageProcesser.go
96 lines (86 loc) · 2.48 KB
/
ImageProcesser.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package docxplate
import (
"context"
"encoding/xml"
"fmt"
"log"
"os"
"path"
"strings"
)
var imgXMLTpl = "<w:pict><v:shape style='width:%dpt;height:%dpt'><v:imagedata r:id='%s'/></v:shape></w:pict>"
// Process image placeholder - add file, rels and return replace val
func processImage(img *Image) (imgXMLStr string, err error) {
var imgPath string
imgPath = img.Path // default
if img.Path == "" {
imgPath, err = DefaultDownloader.DownloadFile(context.Background(), img.URL)
if err != nil {
return
}
defer func() {
if err := os.Remove(imgPath); err != nil {
log.Printf("image process: remove: %s", err)
}
}()
}
// Add image to zip
imgBytes, err := os.ReadFile(imgPath) // #nosec G304 - allowed filename as variable here
if err != nil {
return
}
t.added["word/media/"+imgPath] = imgBytes
// Add image content type
var isContainType bool
imgExt := strings.TrimLeft(strings.ToLower(path.Ext(imgPath)), ".")
contentTypesName := "[Content_Types].xml"
contentTypesNode := t.fileToXMLStruct(contentTypesName)
contentTypesNode.iterate(func(node *xmlNode) bool {
if strings.ToLower(node.Attr("Extension")) == imgExt {
isContainType = true
return true
}
return false
})
if !isContainType {
contentTypesNode.addSub(&xmlNode{
XMLName: xml.Name{
Space: "",
Local: "Default",
},
Attrs: []xml.Attr{
{Name: xml.Name{Space: "", Local: "Extension"}, Value: imgExt},
{Name: xml.Name{Space: "", Local: "ContentType"}, Value: "image/" + imgExt},
},
parent: contentTypesNode,
isNew: true,
})
t.modified[contentTypesName] = structToXMLBytes(contentTypesNode)
}
// Add image to relations TODO walk all rels
var relNode *xmlNode
relName := "word/_rels/document.xml.rels"
if relNodeBytes, ok := t.modified[relName]; ok {
relNode = t.bytesToXMLStruct(relNodeBytes)
} else {
relNode = t.fileToXMLStruct(relName)
}
rid := fmt.Sprintf("rId%d", relNode.childLenght+1)
relNode.addSub(&xmlNode{
XMLName: xml.Name{
Space: "",
Local: "Relationship",
},
Attrs: []xml.Attr{
{Name: xml.Name{Space: "", Local: "Id"}, Value: rid},
{Name: xml.Name{Space: "", Local: "Type"}, Value: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"},
{Name: xml.Name{Space: "", Local: "Target"}, Value: "media/" + imgPath},
},
parent: relNode,
isNew: true,
})
t.modified[relName] = structToXMLBytes(relNode)
// Get replace xml of image
imgXMLStr = fmt.Sprintf(imgXMLTpl, img.Width, img.Height, rid)
return
}