-
Notifications
You must be signed in to change notification settings - Fork 0
/
image.go
130 lines (113 loc) · 2.67 KB
/
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
// Copyright 2015 The present-tex Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"fmt"
"image"
"log"
"os"
"os/exec"
"strings"
_ "image/gif"
_ "image/jpeg"
_ "image/png"
_ "golang.org/x/image/bmp"
_ "golang.org/x/image/tiff"
_ "golang.org/x/image/vp8"
_ "golang.org/x/image/webp"
"golang.org/x/tools/present"
)
type Image struct {
present.Image
HasCaption bool
Caption present.Caption
}
func parseImages(doc *present.Doc) error {
var err error
for i := range doc.Sections {
section := &doc.Sections[i]
for j := range section.Elem {
elem := section.Elem[j]
switch elem := elem.(type) {
default:
continue
case present.Image:
err = parseImage(&elem)
if err != nil {
return fmt.Errorf("could not parse image %q: %w", elem.URL, err)
}
img := Image{Image: elem}
if j+1 < len(section.Elem) {
if elem, ok := section.Elem[j+1].(present.Caption); ok {
err = parseCaption(&elem)
if err != nil {
return err
}
img.HasCaption = true
img.Caption = elem
}
}
section.Elem[j] = img
}
}
}
if err != nil {
return fmt.Errorf("could not parse images: %w", err)
}
return parseCaptions(doc)
}
func parseImage(elem *present.Image) error {
var err error
if strings.HasSuffix(elem.URL, ".svg") {
oname := elem.URL[:len(elem.URL)-len(".svg")] + "_svg.png"
err := exec.Command("convert", elem.URL, oname).Run()
if err != nil {
log.Printf("could not convert SVG image %q to PNG: %+v", elem.URL, err)
// return fmt.Errorf(
// "could not convert SVG image %q to PNG: %w",
// elem.URL, err,
// )
}
elem.URL = oname
}
if elem.Height == 0 || elem.Width == 0 {
f, err := os.Open(elem.URL)
if err != nil {
return fmt.Errorf(
"error opening file [%s]: %w",
elem.URL,
err,
)
}
defer f.Close()
img, _, err := image.Decode(f)
if err != nil {
return fmt.Errorf(
"error decoding image file [%s]: %w",
elem.URL,
err,
)
}
h := img.Bounds().Dy()
w := img.Bounds().Dx()
switch {
case elem.Height == 0 && elem.Width == 0:
elem.Height = h
elem.Width = w
case elem.Height == 0 && elem.Width != 0:
// rescale, keeping ratio
ratio := float64(elem.Width) / float64(w)
elem.Height = int(float64(h) * ratio)
case elem.Height != 0 && elem.Width == 0:
// rescale, keeping ratio
ratio := float64(elem.Height) / float64(h)
elem.Width = int(float64(w) * ratio)
}
}
// rescale height/width to a (default=72) DPI resolution
// height and width are now in inches.
elem.Height /= *dpi
elem.Width /= *dpi
return err
}