ires 0.3.1 → 1.0.0
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/README.md +3 -3
- data/ext/ires/image.go +87 -87
- data/ext/ires/ires.go +67 -65
- data/ext/ires/uri.go +30 -30
- data/lib/ires/service.rb +4 -3
- data/lib/ires/version.rb +1 -1
- data/lib/ires/view_helper.rb +5 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 573e3e3d26bbe6a54df1d21e5445287b94eb628e
|
4
|
+
data.tar.gz: a29209459ec9bb7dea651db214c3440db9cbd09c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7dfe086ce436074e319636b71eafa3736721c71a0c3c7bb175723e4279c15f6282d3aa72bc181d080798440612f2f70ba8ccaa3b40b2deebaad40f58a86ea3dc
|
7
|
+
data.tar.gz: f10ae44af632f4ed0fae261a3e26cba54985006e95913350fcde7cbba1e618037bccd5e0c69775c28cc9c2648f1498a37d51f78d115c061d87f440211feb1cde
|
data/README.md
CHANGED
@@ -11,10 +11,10 @@
|
|
11
11
|
|
12
12
|
```erb
|
13
13
|
<!-- Usually -->
|
14
|
-
<%= ires_tag(
|
14
|
+
<%= ires_tag(path: "image_01.jpg", width: 90, height: 120) %>
|
15
15
|
|
16
16
|
<!-- Using image_tag options -->
|
17
|
-
<%= ires_tag(
|
17
|
+
<%= ires_tag(path: "http://example.com/image_02.jpg", width: 200, height: 200, Ires::Mode::CROP, alt: "example image") %>
|
18
18
|
```
|
19
19
|
|
20
20
|
### Get resize path
|
@@ -47,7 +47,7 @@ Filter of resize image.
|
|
47
47
|
Default: **30days**
|
48
48
|
|
49
49
|
```erb
|
50
|
-
<%= ires_tag(
|
50
|
+
<%= ires_tag(path: '/image.jpg', width: 400, height: 300, expire: 7.days) %>
|
51
51
|
```
|
52
52
|
|
53
53
|
### Saved directory
|
data/ext/ires/image.go
CHANGED
@@ -1,48 +1,48 @@
|
|
1
1
|
package ires
|
2
2
|
|
3
3
|
import (
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
4
|
+
"bytes"
|
5
|
+
"image"
|
6
|
+
"image/gif"
|
7
|
+
"image/jpeg"
|
8
|
+
"image/png"
|
9
|
+
"io"
|
10
|
+
"io/ioutil"
|
11
|
+
"net/http"
|
12
|
+
"os"
|
13
|
+
"path"
|
14
|
+
"strings"
|
15
|
+
"time"
|
16
16
|
|
17
|
-
|
18
|
-
|
17
|
+
"github.com/nfnt/resize"
|
18
|
+
"github.com/oliamb/cutter"
|
19
19
|
)
|
20
20
|
|
21
21
|
// Check expiration date
|
22
22
|
func (i *Ires) DeleteExpireImage() {
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
23
|
+
today := time.Now().Format("20060102")
|
24
|
+
dir := i.readImageDir()
|
25
|
+
files, err := ioutil.ReadDir(dir)
|
26
|
+
if err != nil {
|
27
|
+
return
|
28
|
+
}
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
30
|
+
for _, file := range files {
|
31
|
+
findName := file.Name()
|
32
|
+
matched, _ := path.Match(today+"_*", findName)
|
33
|
+
if matched {
|
34
|
+
deleteImage(path.Join(dir, findName))
|
35
|
+
}
|
36
|
+
}
|
37
37
|
}
|
38
38
|
|
39
39
|
// Input image type is Local or HTTP
|
40
40
|
func (i *Ires) CheckLocal() {
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
41
|
+
if strings.Index(i.URI, "http") == -1 {
|
42
|
+
i.IsLocal = true
|
43
|
+
} else {
|
44
|
+
i.IsLocal = false
|
45
|
+
}
|
46
46
|
}
|
47
47
|
|
48
48
|
// Input image
|
@@ -50,11 +50,11 @@ func (i *Ires) inputImage() bool {
|
|
50
50
|
if i.IsLocal {
|
51
51
|
img, format := localImage(i.URI)
|
52
52
|
i.InputImage = &InputImage{
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
53
|
+
Image: img,
|
54
|
+
Format: format,
|
55
|
+
URI: i.URI,
|
56
|
+
}
|
57
|
+
i.setConfig()
|
58
58
|
return true
|
59
59
|
}
|
60
60
|
return i.downloadImage()
|
@@ -63,30 +63,30 @@ func (i *Ires) inputImage() bool {
|
|
63
63
|
// Save http image
|
64
64
|
func (i *Ires) downloadImage() bool {
|
65
65
|
res, err := http.Get(i.URI)
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
66
|
+
if err != nil {
|
67
|
+
return false
|
68
|
+
}
|
69
|
+
defer res.Body.Close()
|
70
70
|
|
71
|
-
|
72
|
-
|
71
|
+
header, r := copyReader(res.Body)
|
72
|
+
format := formatSearch(r)
|
73
73
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
74
|
+
img, _, err := image.Decode(io.MultiReader(header, res.Body))
|
75
|
+
if err != nil {
|
76
|
+
return false
|
77
|
+
}
|
78
78
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
79
|
+
distURI := i.imageURI(true)
|
80
|
+
i.InputImage = &InputImage{
|
81
|
+
Image: img,
|
82
|
+
Format: format,
|
83
|
+
URI: distURI,
|
84
|
+
}
|
85
85
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
86
|
+
if createImage(img, distURI, format) {
|
87
|
+
i.setConfig()
|
88
|
+
return true
|
89
|
+
}
|
90
90
|
return false
|
91
91
|
}
|
92
92
|
|
@@ -114,7 +114,7 @@ func createImage(img image.Image, path, format string) bool {
|
|
114
114
|
func localImage(uri string) (image.Image, string) {
|
115
115
|
file, err := os.Open(uri)
|
116
116
|
if err != nil {
|
117
|
-
|
117
|
+
return nil, ""
|
118
118
|
}
|
119
119
|
defer file.Close()
|
120
120
|
|
@@ -124,29 +124,29 @@ func localImage(uri string) (image.Image, string) {
|
|
124
124
|
|
125
125
|
img, _, err := image.Decode(io.MultiReader(header, file))
|
126
126
|
if err != nil {
|
127
|
-
|
127
|
+
return nil, ""
|
128
128
|
}
|
129
129
|
return img, format
|
130
130
|
}
|
131
131
|
|
132
132
|
// Set image config
|
133
133
|
func (i *Ires) setConfig() {
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
134
|
+
file, err := os.Open(i.InputImage.URI)
|
135
|
+
if err != nil {
|
136
|
+
panic(err)
|
137
|
+
}
|
138
|
+
defer file.Close()
|
139
139
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
140
|
+
conf, _, err := image.DecodeConfig(file)
|
141
|
+
if err != nil {
|
142
|
+
panic(err)
|
143
|
+
}
|
144
|
+
i.InputImage.Config = conf
|
145
145
|
}
|
146
146
|
|
147
147
|
// Resizing & Cropping
|
148
148
|
func (i *Ires) resizeToCrop() image.Image {
|
149
|
-
|
149
|
+
inputImg := i.InputImage.Image
|
150
150
|
var outputImg image.Image
|
151
151
|
isAsp, conf := i.isValidAspectRatio()
|
152
152
|
|
@@ -237,21 +237,21 @@ func copyReader(body io.Reader) (io.Reader, io.Reader) {
|
|
237
237
|
|
238
238
|
// Valid resize type
|
239
239
|
func (i *Ires) validResizeType() bool {
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
240
|
+
config := i.InputImage.Config
|
241
|
+
valid := false
|
242
|
+
switch i.ResizeType {
|
243
|
+
case All:
|
244
|
+
valid = true
|
245
|
+
case Smaller:
|
246
|
+
if config.Width < i.Width && config.Height < i.Height {
|
247
|
+
valid = true
|
248
|
+
}
|
249
|
+
case Larger:
|
250
|
+
if i.Width <= config.Width && i.Height <= config.Height {
|
251
|
+
valid = true
|
252
|
+
}
|
253
|
+
default:
|
254
|
+
valid = true
|
255
|
+
}
|
256
|
+
return valid
|
257
257
|
}
|
data/ext/ires/ires.go
CHANGED
@@ -1,56 +1,58 @@
|
|
1
1
|
package ires
|
2
2
|
|
3
3
|
import (
|
4
|
-
|
4
|
+
"image"
|
5
5
|
|
6
|
-
|
7
|
-
|
6
|
+
"github.com/nfnt/resize"
|
7
|
+
"github.com/oliamb/cutter"
|
8
8
|
)
|
9
9
|
|
10
10
|
type Mode int
|
11
|
+
|
11
12
|
const (
|
12
|
-
|
13
|
-
|
14
|
-
|
13
|
+
Resize Mode = iota
|
14
|
+
Crop
|
15
|
+
ResizeToCrop
|
15
16
|
)
|
16
17
|
|
17
18
|
type ResizeType int
|
19
|
+
|
18
20
|
const (
|
19
|
-
|
20
|
-
|
21
|
-
|
21
|
+
All ResizeType = iota
|
22
|
+
Smaller
|
23
|
+
Larger
|
22
24
|
)
|
23
25
|
|
24
26
|
type (
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
27
|
+
// Size is ...
|
28
|
+
Size struct {
|
29
|
+
Width, Height int
|
30
|
+
}
|
31
|
+
|
32
|
+
// InputImage is ...
|
33
|
+
InputImage struct {
|
34
|
+
Image image.Image
|
35
|
+
Config image.Config
|
36
|
+
Format string
|
37
|
+
URI string
|
38
|
+
}
|
39
|
+
|
40
|
+
// Ires is ...
|
41
|
+
Ires struct {
|
42
|
+
Size
|
43
|
+
ResizeType
|
44
|
+
Mode
|
45
|
+
*InputImage
|
46
|
+
URI string
|
47
|
+
Dir string
|
48
|
+
Expire string
|
49
|
+
IsLocal bool
|
50
|
+
}
|
49
51
|
)
|
50
52
|
|
51
53
|
// Resize is ...
|
52
54
|
func (i *Ires) Resize() string {
|
53
|
-
|
55
|
+
i.Mode = Resize
|
54
56
|
distURI := i.imageURI(false)
|
55
57
|
// When the image exists, return the image path
|
56
58
|
if isExistsImage(distURI) {
|
@@ -63,46 +65,46 @@ func (i *Ires) Resize() string {
|
|
63
65
|
|
64
66
|
var outputImg image.Image
|
65
67
|
if i.validResizeType() {
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
68
|
+
outputImg = resize.Resize(uint(i.Width), uint(i.Height), i.InputImage.Image, resize.Lanczos3)
|
69
|
+
} else {
|
70
|
+
outputImg = i.InputImage.Image
|
71
|
+
}
|
70
72
|
createImage(outputImg, distURI, i.InputImage.Format)
|
71
73
|
return i.targetImageURI(distURI)
|
72
74
|
}
|
73
75
|
|
74
76
|
// Crop is Crop ...
|
75
77
|
func (i *Ires) Crop() string {
|
76
|
-
|
77
|
-
|
78
|
+
i.Mode = Crop
|
79
|
+
distURI := i.imageURI(false)
|
78
80
|
// When the image exists, return the image path
|
79
81
|
if isExistsImage(distURI) {
|
80
|
-
|
81
|
-
|
82
|
+
return i.targetImageURI(distURI)
|
83
|
+
}
|
82
84
|
|
83
85
|
if !i.inputImage() {
|
84
86
|
return i.URI
|
85
87
|
}
|
86
88
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
89
|
+
var outputImg image.Image
|
90
|
+
if i.validResizeType() {
|
91
|
+
outputImg, _ = cutter.Crop(i.InputImage.Image, cutter.Config{
|
92
|
+
Width: i.Width,
|
93
|
+
Height: i.Height,
|
94
|
+
Mode: cutter.Centered,
|
95
|
+
Options: cutter.Copy,
|
96
|
+
})
|
97
|
+
} else {
|
98
|
+
outputImg = i.InputImage.Image
|
99
|
+
}
|
100
|
+
createImage(outputImg, distURI, i.InputImage.Format)
|
101
|
+
return i.targetImageURI(distURI)
|
100
102
|
}
|
101
103
|
|
102
104
|
// ResizeToCrop is ...
|
103
105
|
func (i *Ires) ResizeToCrop() string {
|
104
|
-
|
105
|
-
|
106
|
+
i.Mode = ResizeToCrop
|
107
|
+
distURI := i.imageURI(false)
|
106
108
|
// When the image exists, return the image path
|
107
109
|
if isExistsImage(distURI) {
|
108
110
|
return i.targetImageURI(distURI)
|
@@ -112,12 +114,12 @@ func (i *Ires) ResizeToCrop() string {
|
|
112
114
|
return i.URI
|
113
115
|
}
|
114
116
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
117
|
+
var outputImg image.Image
|
118
|
+
if i.validResizeType() {
|
119
|
+
outputImg = i.resizeToCrop()
|
120
|
+
} else {
|
121
|
+
outputImg = i.InputImage.Image
|
122
|
+
}
|
123
|
+
createImage(outputImg, distURI, i.InputImage.Format)
|
124
|
+
return i.targetImageURI(distURI)
|
123
125
|
}
|
data/ext/ires/uri.go
CHANGED
@@ -40,36 +40,36 @@ func (i *Ires) imageURI(original bool) string {
|
|
40
40
|
|
41
41
|
// Generate image name
|
42
42
|
func (i *Ires) imageName(original bool) string {
|
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
|
-
|
43
|
+
splitPath := strings.Split(i.URI, "/")
|
44
|
+
|
45
|
+
// ex. sample.jpg
|
46
|
+
fileName := splitPath[len(splitPath)-1]
|
47
|
+
// ex. .jpg
|
48
|
+
ext := filepath.Ext(fileName)
|
49
|
+
|
50
|
+
name := strings.Replace(fileName, ext, "", 1)
|
51
|
+
|
52
|
+
extInfo := strings.Split(ext, "?")
|
53
|
+
if len(extInfo) > 1 {
|
54
|
+
ext = extInfo[0]
|
55
|
+
name += "_" + strings.Join(extInfo[1:], "")
|
56
|
+
}
|
57
|
+
|
58
|
+
var prefix string
|
59
|
+
if original {
|
60
|
+
prefix = "original"
|
61
|
+
} else {
|
62
|
+
switch i.Mode {
|
63
|
+
case Resize:
|
64
|
+
prefix = prefixSize(i.Size) + "_resize"
|
65
|
+
case Crop:
|
66
|
+
prefix = prefixSize(i.Size) + "_crop"
|
67
|
+
case ResizeToCrop:
|
68
|
+
prefix = prefixSize(i.Size) + "_resize_to_crop"
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
return i.Expire + "_" + name + "_" + prefix + ext
|
73
73
|
}
|
74
74
|
|
75
75
|
// Create prefix by size
|
data/lib/ires/service.rb
CHANGED
@@ -8,7 +8,8 @@ module Ires
|
|
8
8
|
class << self
|
9
9
|
# Resize image path
|
10
10
|
# @return [String]
|
11
|
-
def path(path:, width
|
11
|
+
def path(path:, width: nil, height: nil, type: Type::ALL, mode: Mode::RESIZE, expire: 30.days)
|
12
|
+
raise ArgumentError, "Either width or height is required" if width.nil? && height.nil?
|
12
13
|
os = Ires::Os.current
|
13
14
|
return nil if os.nil?
|
14
15
|
|
@@ -22,8 +23,8 @@ module Ires
|
|
22
23
|
|
23
24
|
ires_element = {
|
24
25
|
path: full_path,
|
25
|
-
width: width,
|
26
|
-
height: height,
|
26
|
+
width: width || 0,
|
27
|
+
height: height || 0,
|
27
28
|
mode: mode,
|
28
29
|
type: type,
|
29
30
|
dir: dir,
|
data/lib/ires/version.rb
CHANGED
data/lib/ires/view_helper.rb
CHANGED
@@ -8,11 +8,13 @@ module Ires
|
|
8
8
|
module ViewHelper
|
9
9
|
# Image resize
|
10
10
|
# @return [image_tag]
|
11
|
-
def ires_tag(path:, width
|
11
|
+
def ires_tag(path:, width: nil, height: nil, type: Type::ALL, mode: Mode::RESIZE, expire: 30.days, **option)
|
12
|
+
raise ArgumentError, "Either width or height is required" if width.nil? && height.nil?
|
13
|
+
|
12
14
|
image = Ires::Service.path(
|
13
15
|
path: path,
|
14
|
-
width: width,
|
15
|
-
height: height,
|
16
|
+
width: width || 0,
|
17
|
+
height: height || 0,
|
16
18
|
mode: mode,
|
17
19
|
type: type,
|
18
20
|
expire: expire
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ires
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- enta0701
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-11-
|
11
|
+
date: 2018-11-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|