-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcut.go
103 lines (93 loc) · 2.46 KB
/
cut.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
// Package imageEncrypt cut is Cutting Image
package imageEncrypt
import (
"image"
"io"
"path/filepath"
"strconv"
"strings"
"sync"
"github.com/sosop/imaging"
)
const (
// DefaultPatitionX default cols
DefaultPatitionX = 4
// DefaultPatitionY default rows
DefaultPatitionY = 4
)
// Cut interface
type Cut interface {
Cutting(reader io.Reader, filename string, condition ...interface{}) (MetaCuttedImage, error)
}
// RectangleCut cutting image to litle Rectangle image
type RectangleCut struct {
// cols
partitionX int
// rows
partitionY int
// Image Storage Interface
storage Storage
// Meta-information storage interface
meta Meta
}
// NewDefaultRectangleCut constructor
func NewDefaultRectangleCut(storage Storage, meta Meta) *RectangleCut {
return NewRectangleCut(DefaultPatitionX, DefaultPatitionY, storage, meta)
}
// NewRectangleCut constructor
func NewRectangleCut(partitionX, patitionY int, storage Storage, meta Meta) *RectangleCut {
return &RectangleCut{partitionX: partitionX, partitionY: patitionY, storage: storage, meta: meta}
}
// Cutting implement the interface of Cut
func (r RectangleCut) Cutting(reader io.Reader, filename string, condition ...interface{}) (*MetaCuttedImage, error) {
ext := strings.ToLower(filepath.Ext(filename))
src, err := imaging.Decode(reader)
if err != nil {
return nil, err
}
rect := src.Bounds()
x := rect.Max.X - rect.Min.X
y := rect.Max.Y - rect.Min.X
// step of x
stepX := x / r.partitionX
// step of y
stepY := y / r.partitionY
images := make([]CuttedImage, r.partitionX*r.partitionY)
k := 0
// goroutine save splice image
wg := new(sync.WaitGroup)
wg.Add(r.partitionX * r.partitionY)
for row := 0; row < r.partitionY; row++ {
for col := 0; col < r.partitionX; col++ {
images[k] = CuttedImage{ID: k}
p1 := Point{}
p2 := Point{}
if col > 0 {
p1.X = images[k-1].Points[1].X
}
if row > 0 {
p1.Y = images[k-r.partitionX].Points[1].Y
}
if col == r.partitionX-1 {
p2.X = x
} else {
p2.X = p1.X + stepX
}
if row == r.partitionY-1 {
p2.Y = y
} else {
p2.Y = p1.Y + stepY
}
images[k].Points = []Point{p1, p2}
retangle := image.Rect(p1.X, p1.Y, p2.X, p2.Y)
subImg := imaging.Crop(src, retangle)
img := rotate(subImg, &images[k])
go r.storage.Save(&images[k], img, strconv.Itoa(k)+filename, wg, ext)
k++
}
}
wg.Wait()
metaImage := MetaCuttedImage{images, x, y, Rectangle, ext}
r.meta.Save(metaImage, condition...)
return &metaImage, nil
}