ires 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/ires/ires.go +114 -0
- data/ext/main.go +22 -76
- data/ext/operate/image.go +54 -17
- data/ext/vendor/github.com/satori/go.uuid/LICENSE +20 -0
- data/ext/vendor/github.com/satori/go.uuid/README.md +65 -0
- data/ext/vendor/github.com/satori/go.uuid/benchmarks_test.go +121 -0
- data/ext/vendor/github.com/satori/go.uuid/uuid.go +488 -0
- data/ext/vendor/github.com/satori/go.uuid/uuid_test.go +633 -0
- data/lib/ires/version.rb +1 -1
- data/shared/darwin/ires.so +0 -0
- data/shared/linux/ires.so +0 -0
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 251701d58fac515d1934c13b3918f2f8b2bc78de
|
4
|
+
data.tar.gz: 1896850d80b1efacc2e2c9d30fdea8c54554090a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 53ce5e4d3f6772cc8e0693ba100ccfc597c1dc45b66cfb12725e654086e5f568e68b3f596e6ed6edf48e837def11d480ce2ae8a5848953da8aa27bf1958a3bd4
|
7
|
+
data.tar.gz: c51b9cac6a3057f9cb61c0be82e0590a5e0413f59cfebe6e61bd3b6aa4e4270dfd09b5d2125f19bd0c7600822b67c4116a25a63a2e4391a08cb707b0be5c461f
|
data/ext/ires/ires.go
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
package ires
|
2
|
+
|
3
|
+
import (
|
4
|
+
"strings"
|
5
|
+
|
6
|
+
"github.com/endotakuya/ires/ext/operate"
|
7
|
+
"github.com/endotakuya/ires/ext/util/uri"
|
8
|
+
"github.com/nfnt/resize"
|
9
|
+
"github.com/oliamb/cutter"
|
10
|
+
)
|
11
|
+
|
12
|
+
const (
|
13
|
+
IMAGE_MODE_RESIZE int = iota
|
14
|
+
IMAGE_MODE_CROP
|
15
|
+
IMAGE_MODE_RESIZE_TO_CROP
|
16
|
+
IMAGE_MODE_ORIGINAL
|
17
|
+
)
|
18
|
+
|
19
|
+
type Request struct {
|
20
|
+
Uri string
|
21
|
+
Width int
|
22
|
+
Height int
|
23
|
+
Dir string
|
24
|
+
Expire string
|
25
|
+
}
|
26
|
+
|
27
|
+
|
28
|
+
func (r *Request) Resize() string {
|
29
|
+
size := []int{r.Width, r.Height}
|
30
|
+
|
31
|
+
// Delete the expiration date image
|
32
|
+
util.DeleteExpireImage(r.Uri, r.Dir, IMAGE_MODE_RESIZE, size...)
|
33
|
+
|
34
|
+
path := r.fullPath(IMAGE_MODE_RESIZE)
|
35
|
+
// When the image exists, return the image path
|
36
|
+
if util.IsExistsImage(path) {
|
37
|
+
return r.imagePath(path)
|
38
|
+
}
|
39
|
+
|
40
|
+
inputImg, format, isImageExist := operate.InputImage(r.Uri, r.originalFullPath())
|
41
|
+
if !isImageExist {
|
42
|
+
return r.Uri
|
43
|
+
}
|
44
|
+
|
45
|
+
outputImg := resize.Resize(uint(r.Width), uint(r.Height), inputImg, resize.Lanczos3)
|
46
|
+
_, fullPath, _ := operate.CreateImage(outputImg, path, format)
|
47
|
+
|
48
|
+
return r.imagePath(fullPath)
|
49
|
+
}
|
50
|
+
|
51
|
+
func (r *Request) Crop() string {
|
52
|
+
size := []int{r.Width, r.Height}
|
53
|
+
|
54
|
+
// Delete the expiration date image
|
55
|
+
util.DeleteExpireImage(r.Uri, r.Dir, IMAGE_MODE_CROP, size...)
|
56
|
+
|
57
|
+
path := r.fullPath(IMAGE_MODE_CROP)
|
58
|
+
// When the image exists, return the image path
|
59
|
+
if util.IsExistsImage(path) {
|
60
|
+
return r.imagePath(path)
|
61
|
+
}
|
62
|
+
|
63
|
+
inputImg, format, isImageExist := operate.InputImage(r.Uri, r.originalFullPath())
|
64
|
+
if !isImageExist {
|
65
|
+
return r.Uri
|
66
|
+
}
|
67
|
+
|
68
|
+
outputImg, _ := cutter.Crop(inputImg, cutter.Config{
|
69
|
+
Width: r.Width,
|
70
|
+
Height: r.Height,
|
71
|
+
Mode: cutter.Centered,
|
72
|
+
Options: cutter.Copy,
|
73
|
+
})
|
74
|
+
_, fullPath, _ := operate.CreateImage(outputImg, path, format)
|
75
|
+
|
76
|
+
return r.imagePath(fullPath)
|
77
|
+
}
|
78
|
+
|
79
|
+
func (r *Request) ResizeToCrop() string {
|
80
|
+
size := []int{r.Width, r.Height}
|
81
|
+
|
82
|
+
// Delete the expiration date image
|
83
|
+
util.DeleteExpireImage(r.Uri, r.Dir, IMAGE_MODE_RESIZE_TO_CROP, size...)
|
84
|
+
|
85
|
+
path := r.fullPath(IMAGE_MODE_RESIZE_TO_CROP)
|
86
|
+
// When the image exists, return the image path
|
87
|
+
if util.IsExistsImage(path) {
|
88
|
+
return r.imagePath(path)
|
89
|
+
}
|
90
|
+
|
91
|
+
originalImagePath := r.originalFullPath()
|
92
|
+
inputImg, format, isImageExist := operate.InputImage(r.Uri, originalImagePath)
|
93
|
+
if !isImageExist {
|
94
|
+
return r.Uri
|
95
|
+
}
|
96
|
+
|
97
|
+
outputImg := operate.ResizeToCrop(originalImagePath, size, inputImg)
|
98
|
+
_, fullPath, _ := operate.CreateImage(outputImg, path, format)
|
99
|
+
|
100
|
+
return r.imagePath(fullPath)
|
101
|
+
}
|
102
|
+
|
103
|
+
func (r *Request) fullPath(mode int) string {
|
104
|
+
size := []int{ r.Width, r.Height }
|
105
|
+
return util.NewImagePath(r.Uri, r.Dir, r.Expire, mode, size...)
|
106
|
+
}
|
107
|
+
|
108
|
+
func (r *Request) originalFullPath() string {
|
109
|
+
return util.NewImagePath(r.Uri, r.Dir, r.Expire, IMAGE_MODE_ORIGINAL)
|
110
|
+
}
|
111
|
+
|
112
|
+
func (r *Request) imagePath(fullPath string) string {
|
113
|
+
return strings.Replace(fullPath, r.Dir, "", -1)
|
114
|
+
}
|
data/ext/main.go
CHANGED
@@ -2,19 +2,8 @@ package main
|
|
2
2
|
|
3
3
|
import (
|
4
4
|
"C"
|
5
|
-
"strings"
|
6
5
|
|
7
|
-
"github.com/
|
8
|
-
"github.com/oliamb/cutter"
|
9
|
-
"github.com/endotakuya/ires/ext/util/uri"
|
10
|
-
"github.com/endotakuya/ires/ext/operate"
|
11
|
-
)
|
12
|
-
|
13
|
-
const (
|
14
|
-
IMAGE_MODE_RESIZE int = iota
|
15
|
-
IMAGE_MODE_CROP
|
16
|
-
IMAGE_MODE_RESIZE_TO_CROP
|
17
|
-
IMAGE_MODE_ORIGINAL
|
6
|
+
"github.com/endotakuya/ires/ext/ires"
|
18
7
|
)
|
19
8
|
|
20
9
|
func init() {}
|
@@ -26,28 +15,15 @@ func resizeImage(Uri *C.char, width, height int, Dir, Expire *C.char) *C.char {
|
|
26
15
|
dir := C.GoString(Dir)
|
27
16
|
expire := C.GoString(Expire)
|
28
17
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
// When the image exists, return the image path
|
37
|
-
if util.IsExistsImage(path) {
|
38
|
-
return C.CString(strings.Replace(path, dir, "", -1))
|
39
|
-
}
|
40
|
-
|
41
|
-
inputImg, _, isImageExist := operate.InputImage(uri, originalPath)
|
42
|
-
if !isImageExist {
|
43
|
-
return C.CString(uri)
|
18
|
+
r := &ires.Request{
|
19
|
+
Uri: uri,
|
20
|
+
Width: width,
|
21
|
+
Height: height,
|
22
|
+
Dir: dir,
|
23
|
+
Expire: expire,
|
44
24
|
}
|
45
|
-
outputImg := resize.Resize(uint(width), uint(height), inputImg, resize.Lanczos3)
|
46
|
-
|
47
|
-
_, filePath, _ := operate.CreateImage(outputImg, path)
|
48
25
|
|
49
|
-
|
50
|
-
return C.CString(fileName)
|
26
|
+
return C.CString(r.Resize())
|
51
27
|
}
|
52
28
|
|
53
29
|
//export cropImage
|
@@ -56,33 +32,15 @@ func cropImage(Uri *C.char, width, height int, Dir, Expire *C.char) *C.char {
|
|
56
32
|
dir := C.GoString(Dir)
|
57
33
|
expire := C.GoString(Expire)
|
58
34
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
// Delete the expiration date image
|
64
|
-
util.DeleteExpireImage(uri, dir, IMAGE_MODE_CROP, size...)
|
65
|
-
|
66
|
-
// When the image exists, return the image path
|
67
|
-
if util.IsExistsImage(path) {
|
68
|
-
return C.CString(strings.Replace(path, dir, "", -1))
|
69
|
-
}
|
70
|
-
|
71
|
-
inputImg, _, isImageExist := operate.InputImage(uri, originalPath)
|
72
|
-
if !isImageExist {
|
73
|
-
return C.CString(uri)
|
74
|
-
}
|
75
|
-
outputImg, _ := cutter.Crop(inputImg, cutter.Config{
|
76
|
-
Width: width,
|
35
|
+
r := &ires.Request{
|
36
|
+
Uri: uri,
|
37
|
+
Width: width,
|
77
38
|
Height: height,
|
78
|
-
|
79
|
-
|
80
|
-
}
|
81
|
-
|
82
|
-
_, filePath, _ := operate.CreateImage(outputImg, path)
|
39
|
+
Dir: dir,
|
40
|
+
Expire: expire,
|
41
|
+
}
|
83
42
|
|
84
|
-
|
85
|
-
return C.CString(fileName)
|
43
|
+
return C.CString(r.Crop())
|
86
44
|
}
|
87
45
|
|
88
46
|
//export resizeToCropImage
|
@@ -91,25 +49,13 @@ func resizeToCropImage(Uri *C.char, width, height int, Dir, Expire *C.char) *C.c
|
|
91
49
|
dir := C.GoString(Dir)
|
92
50
|
expire := C.GoString(Expire)
|
93
51
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
// When the image exists, return the image path
|
102
|
-
if util.IsExistsImage(path) {
|
103
|
-
return C.CString(strings.Replace(path, dir, "", -1))
|
104
|
-
}
|
105
|
-
|
106
|
-
inputImg, imgPath, isImageExist := operate.InputImage(uri, originalPath)
|
107
|
-
if !isImageExist {
|
108
|
-
return C.CString(uri)
|
52
|
+
r := &ires.Request{
|
53
|
+
Uri: uri,
|
54
|
+
Width: width,
|
55
|
+
Height: height,
|
56
|
+
Dir: dir,
|
57
|
+
Expire: expire,
|
109
58
|
}
|
110
|
-
outputImg := operate.ResizeToCrop(imgPath, size, inputImg)
|
111
|
-
_, filePath, _ := operate.CreateImage(outputImg, path)
|
112
59
|
|
113
|
-
|
114
|
-
return C.CString(fileName)
|
60
|
+
return C.CString(r.ResizeToCrop())
|
115
61
|
}
|
data/ext/operate/image.go
CHANGED
@@ -1,8 +1,12 @@
|
|
1
1
|
package operate
|
2
2
|
|
3
3
|
import (
|
4
|
+
"bytes"
|
4
5
|
"image"
|
6
|
+
"image/gif"
|
5
7
|
"image/jpeg"
|
8
|
+
"image/png"
|
9
|
+
"io"
|
6
10
|
"net/http"
|
7
11
|
"os"
|
8
12
|
|
@@ -11,17 +15,19 @@ import (
|
|
11
15
|
"github.com/oliamb/cutter"
|
12
16
|
)
|
13
17
|
|
14
|
-
|
18
|
+
|
15
19
|
func InputImage(uri, path string) (image.Image, string, bool) {
|
16
20
|
if util.IsLocalFile(uri) {
|
17
|
-
|
21
|
+
img, format := LocalImage(uri)
|
22
|
+
return img, format, true
|
18
23
|
} else {
|
19
24
|
img, path, isImageExist := DownloadImage(uri, path)
|
20
25
|
return img, path, isImageExist
|
21
26
|
}
|
22
27
|
}
|
23
28
|
|
24
|
-
|
29
|
+
|
30
|
+
// Save http image
|
25
31
|
func DownloadImage(uri, path string) (image.Image, string, bool) {
|
26
32
|
res, err := http.Get(uri)
|
27
33
|
if err != nil {
|
@@ -29,28 +35,40 @@ func DownloadImage(uri, path string) (image.Image, string, bool) {
|
|
29
35
|
}
|
30
36
|
defer res.Body.Close()
|
31
37
|
|
32
|
-
|
38
|
+
header, r := copyReader(res.Body)
|
39
|
+
format := formatSearch(r)
|
40
|
+
|
41
|
+
img, _, err := image.Decode(io.MultiReader(header, res.Body))
|
33
42
|
if err != nil {
|
34
43
|
return nil, path, false
|
35
44
|
}
|
36
|
-
return CreateImage(img, path)
|
45
|
+
return CreateImage(img, path, format)
|
37
46
|
}
|
38
47
|
|
39
|
-
|
40
|
-
func CreateImage(img image.Image, path string) (image.Image, string, bool) {
|
48
|
+
|
49
|
+
func CreateImage(img image.Image, path, format string) (image.Image, string, bool) {
|
41
50
|
file, err := os.Create(path)
|
42
51
|
if err != nil {
|
43
52
|
panic(err)
|
44
53
|
}
|
45
54
|
defer file.Close()
|
46
55
|
|
47
|
-
|
56
|
+
switch format {
|
57
|
+
case "jpeg":
|
58
|
+
jpeg.Encode(file, img, nil)
|
59
|
+
case "png":
|
60
|
+
png.Encode(file, img)
|
61
|
+
case "gif":
|
62
|
+
gif.Encode(file, img, nil)
|
63
|
+
default:
|
64
|
+
jpeg.Encode(file, img, nil)
|
65
|
+
}
|
48
66
|
|
49
|
-
return
|
67
|
+
return img, path, true
|
50
68
|
}
|
51
69
|
|
52
|
-
|
53
|
-
func LocalImage(uri string) image.Image {
|
70
|
+
|
71
|
+
func LocalImage(uri string) (image.Image, string) {
|
54
72
|
file, err := os.Open(uri)
|
55
73
|
if err != nil{
|
56
74
|
panic(err)
|
@@ -58,14 +76,17 @@ func LocalImage(uri string) image.Image {
|
|
58
76
|
defer file.Close()
|
59
77
|
|
60
78
|
// Decode jpeg into image.Image
|
61
|
-
|
79
|
+
header, r := copyReader(file)
|
80
|
+
format := formatSearch(r)
|
81
|
+
|
82
|
+
img, _, err := image.Decode(io.MultiReader(header, file))
|
62
83
|
if err != nil {
|
63
84
|
panic(err)
|
64
85
|
}
|
65
|
-
return img
|
86
|
+
return img, format
|
66
87
|
}
|
67
88
|
|
68
|
-
|
89
|
+
|
69
90
|
func ResizeToCrop(path string, size []int, inputImg image.Image) image.Image {
|
70
91
|
var outputImg image.Image
|
71
92
|
isAsp, conf := isValidAspectRatio(path, size)
|
@@ -98,7 +119,7 @@ func ResizeToCrop(path string, size []int, inputImg image.Image) image.Image {
|
|
98
119
|
return outputImg
|
99
120
|
}
|
100
121
|
|
101
|
-
|
122
|
+
|
102
123
|
func isValidAspectRatio(path string, size []int) (bool, image.Config) {
|
103
124
|
conf := imageConfig(path)
|
104
125
|
aspH := (conf.Height * size[0]) / conf.Width
|
@@ -109,7 +130,7 @@ func isValidAspectRatio(path string, size []int) (bool, image.Config) {
|
|
109
130
|
}
|
110
131
|
}
|
111
132
|
|
112
|
-
|
133
|
+
|
113
134
|
func imageConfig(path string) image.Config {
|
114
135
|
file, err := os.Open(path)
|
115
136
|
if err != nil {
|
@@ -124,7 +145,7 @@ func imageConfig(path string) image.Config {
|
|
124
145
|
return conf
|
125
146
|
}
|
126
147
|
|
127
|
-
|
148
|
+
|
128
149
|
func resizeMode(conf image.Config, size []int) int {
|
129
150
|
if conf.Width >= conf.Height && size[0] >= size[1] {
|
130
151
|
return 1
|
@@ -136,4 +157,20 @@ func resizeMode(conf image.Config, size []int) int {
|
|
136
157
|
return 4
|
137
158
|
}
|
138
159
|
return 0
|
160
|
+
}
|
161
|
+
|
162
|
+
|
163
|
+
func formatSearch(r io.Reader) string{
|
164
|
+
_, format, err := image.DecodeConfig(r)
|
165
|
+
if err != nil {
|
166
|
+
return "jpeg"
|
167
|
+
}
|
168
|
+
return format
|
169
|
+
}
|
170
|
+
|
171
|
+
|
172
|
+
func copyReader(body io.Reader) (io.Reader, io.Reader) {
|
173
|
+
header := bytes.NewBuffer(nil)
|
174
|
+
r := io.TeeReader(body, header)
|
175
|
+
return header, r
|
139
176
|
}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (C) 2013-2016 by Maxim Bublis <b@codemonkey.ru>
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# UUID package for Go language
|
2
|
+
|
3
|
+
[](https://travis-ci.org/satori/go.uuid)
|
4
|
+
[](https://coveralls.io/github/satori/go.uuid)
|
5
|
+
[](http://godoc.org/github.com/satori/go.uuid)
|
6
|
+
|
7
|
+
This package provides pure Go implementation of Universally Unique Identifier (UUID). Supported both creation and parsing of UUIDs.
|
8
|
+
|
9
|
+
With 100% test coverage and benchmarks out of box.
|
10
|
+
|
11
|
+
Supported versions:
|
12
|
+
* Version 1, based on timestamp and MAC address (RFC 4122)
|
13
|
+
* Version 2, based on timestamp, MAC address and POSIX UID/GID (DCE 1.1)
|
14
|
+
* Version 3, based on MD5 hashing (RFC 4122)
|
15
|
+
* Version 4, based on random numbers (RFC 4122)
|
16
|
+
* Version 5, based on SHA-1 hashing (RFC 4122)
|
17
|
+
|
18
|
+
## Installation
|
19
|
+
|
20
|
+
Use the `go` command:
|
21
|
+
|
22
|
+
$ go get github.com/satori/go.uuid
|
23
|
+
|
24
|
+
## Requirements
|
25
|
+
|
26
|
+
UUID package requires Go >= 1.2.
|
27
|
+
|
28
|
+
## Example
|
29
|
+
|
30
|
+
```go
|
31
|
+
package main
|
32
|
+
|
33
|
+
import (
|
34
|
+
"fmt"
|
35
|
+
"github.com/satori/go.uuid"
|
36
|
+
)
|
37
|
+
|
38
|
+
func main() {
|
39
|
+
// Creating UUID Version 4
|
40
|
+
u1 := uuid.NewV4()
|
41
|
+
fmt.Printf("UUIDv4: %s\n", u1)
|
42
|
+
|
43
|
+
// Parsing UUID from string input
|
44
|
+
u2, err := uuid.FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
|
45
|
+
if err != nil {
|
46
|
+
fmt.Printf("Something gone wrong: %s", err)
|
47
|
+
}
|
48
|
+
fmt.Printf("Successfully parsed: %s", u2)
|
49
|
+
}
|
50
|
+
```
|
51
|
+
|
52
|
+
## Documentation
|
53
|
+
|
54
|
+
[Documentation](http://godoc.org/github.com/satori/go.uuid) is hosted at GoDoc project.
|
55
|
+
|
56
|
+
## Links
|
57
|
+
* [RFC 4122](http://tools.ietf.org/html/rfc4122)
|
58
|
+
* [DCE 1.1: Authentication and Security Services](http://pubs.opengroup.org/onlinepubs/9696989899/chap5.htm#tagcjh_08_02_01_01)
|
59
|
+
|
60
|
+
## Copyright
|
61
|
+
|
62
|
+
Copyright (C) 2013-2016 by Maxim Bublis <b@codemonkey.ru>.
|
63
|
+
|
64
|
+
UUID package released under MIT License.
|
65
|
+
See [LICENSE](https://github.com/satori/go.uuid/blob/master/LICENSE) for details.
|