-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathget_go_image.go
151 lines (128 loc) · 4.1 KB
/
get_go_image.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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package main
import (
"errors"
"fmt"
"image"
"io/ioutil"
"mime/multipart"
"os"
"os/exec"
"path"
"strings"
)
func formFileToImage(serverFile multipart.File, contentType string, supported Supported) (img image.Image, cropAlignTop bool, err error) {
// Just to be sure we have an extra close here
defer serverFile.Close()
switch contentType {
case "image/webp", "image/png", "image/jpeg", "image/gif":
// Parse the image
img, _, err = image.Decode(serverFile)
return img, false, err
case "application/pdf", "application/x-pdf", "application/x-bzpdf", "application/x-gzpdf":
if !supported.PdfToCairo {
if supported.LibreOffice {
// libre office can also convert PDFs to images :)
img, err = convertOfficeToImageFromBytes(serverFile)
return img, true, err
}
return nil, false, fmt.Errorf("unsupported file content type %s", contentType)
}
// Create temp file with contents of input
filename, err := createTempFile(serverFile, "pdf")
if err != nil {
return nil, false, err
}
defer os.Remove(filename)
// Convert the file to a image
img, err = convertPdfToImage(filename)
return img, true, err
case
"application/vnd.oasis.opendocument.text", // .odt
"text/csv", // .csv
"application/msword", // .doc
"application/vnd.openxmlformats-officedocument.wordprocessingml.document", // .docx
"application/vnd.openxmlformats-officedocument.presentationml.presentation", // .pptx
"application/mspowerpoint", // .ppt
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", // .xlsx
"application/msexcel": // .xls
if !supported.LibreOffice {
return nil, false, fmt.Errorf("unsupported file content type %s", contentType)
}
cropAlignTop = true
img, err = convertOfficeToImageFromBytes(serverFile)
return img, true, err
default:
return nil, false, fmt.Errorf("unsupported file content type %s", contentType)
}
}
func convertOfficeToImageFromBytes(serverFile multipart.File) (image.Image, error) {
// Create temp file with contents of input
filename, err := createTempFile(serverFile, "document")
if err != nil {
return nil, err
}
defer os.Remove(filename)
return convertOfficeToImage(filename)
}
func convertOfficeToImage(filename string) (image.Image, error) {
// convert the office file to a png
command := "soffice"
customSofficePath := os.Getenv("SOFFICE_PATH")
if len(customSofficePath) > 0 {
command = customSofficePath
}
err := exec.Command(command, "--headless", "--invisible", "--convert-to", "png", "--outdir", path.Dir(filename), filename).Run()
if err != nil {
return nil, errors.New("unable to read the document")
}
// Read the generated file
outFilename := strings.TrimSuffix(filename, ".document") + ".png"
defer os.Remove(outFilename)
outFileBytes, err := os.Open(outFilename)
if err != nil {
return nil, errors.New("unable to convert document to image")
}
// Parse the image
img, _, err := image.Decode(outFileBytes)
outFileBytes.Close()
if err != nil {
return nil, errors.New("unsupported file format")
}
return img, nil
}
func convertPdfToImage(filename string) (image.Image, error) {
// Convert the pdf file to a png file
err := exec.Command("pdftocairo", filename, "-singlefile", "-png", filename).Run()
if err != nil {
return nil, errors.New("unable to read pdf file")
}
// Read the generated file
outFilename := filename + ".png"
defer os.Remove(outFilename)
outFileBytes, err := os.Open(outFilename)
if err != nil {
return nil, errors.New("unable to convert document to image")
}
// Parse the image
img, _, err := image.Decode(outFileBytes)
outFileBytes.Close()
if err != nil {
return nil, errors.New("unsupported file format")
}
return img, nil
}
func createTempFile(file multipart.File, extension string) (string, error) {
inputFileBytes, err := ioutil.ReadAll(file)
file.Close()
if err != nil {
return "", errors.New("unable to read input file")
}
tempFile, err := os.CreateTemp("", "*."+extension)
if err != nil {
return "", errors.New("unable to convert document to image")
}
filename := tempFile.Name()
tempFile.Write(inputFileBytes)
tempFile.Close()
return filename, nil
}