ires 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b257d1482a34c83c67287636a7370c3531aba5f2
4
- data.tar.gz: 55d3577bf53d61dd0e1fa9084f1b0fe5889b96a1
3
+ metadata.gz: 51c855f31ee4c3154e6f11d0c58e47b1f4b1e360
4
+ data.tar.gz: 9529a56c17f521b8cc669c5169d2416a02e96915
5
5
  SHA512:
6
- metadata.gz: 2aea5907a83563bf3cb4513ab58b8da397e40364e2b3048eb81171c5dbaed1fe48623d61bf21e4f12759161346a65de1d1efca10d0659afe6b0be798d39bd63e
7
- data.tar.gz: 14471ef705b607b8277cccf03b68fa47a7b11de6c37cd9ac5b9d424525779c786eb3309451fd5ff361cd720932d99b0a046e038a97ef69d70a12f9495c883e29
6
+ metadata.gz: 74b58d89cb8f5062b1b1030d26f8ed4db13d298307cabab331b65e5294cc90e6665d4902d1f9775cfaecced305f63eb81d1ef47dff06aa5714d178f08171e3c8
7
+ data.tar.gz: 7a3d4a7eb98710e4ab36f17b96515e8449bb4ea5151de5ea325d3d48c956c83b95b31490aa07fa814b8840084eebb3b31ab1fabf626ad01008e33c55745b7af7
data/README.md CHANGED
@@ -14,31 +14,40 @@
14
14
  <%= ires_tag( path: "image_01.jpg", width: 90, height: 120 ) %>
15
15
 
16
16
  <!-- Using image_tag options -->
17
- <%= ires_tag( path: "http://example.com/image_02.jpg", width: 200, height: 200, mode: "crop", alt: "example image" ) %>
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
21
21
 
22
22
  ```ruby
23
- Ires::Service.path( path: "<FULL IMAGE PATH>", width: 400, height: 300)
23
+ Ires::Service.path(path: '<FULL IMAGE PATH>', width: 400, height: 300)
24
24
  => /ires/<resize image path>
25
25
  ```
26
26
 
27
27
  ### Select mode
28
28
 
29
- | info |    mode     |
30
- |:---------------------------|:--------------------:|
31
- | Resize | resize (default) |
32
- | Cropping | crop |
33
- | Rsize after Cropping | rsize_to_crop |
29
+ | info |    mode     |
30
+ |:---------------------------|:---------------------------------|
31
+ | Resize | Ires::Mode::RESIZE (default) |
32
+ | Cropping | Ires::Mode::CROP |
33
+ | Rsize after Cropping | Ires::Mode::RESIZE_TO_CROP |
34
34
 
35
+ ### Select type
36
+
37
+ Filter of resize image.
38
+
39
+ | info |    type     |
40
+ |:---------------------------|:---------------------------------|
41
+ | All | Ires::Type::ALL (default) |
42
+ | Smaller than | Ires::Type::SMALLER |
43
+ | Larger than | Ires::Type::LARGER |
35
44
 
36
45
  ### Specify cache expiration
37
46
 
38
47
  Default: **30days**
39
48
 
40
49
  ```erb
41
- <%= ires_tag( path: "/image.jpg", width: 400, height: 300, expire: 7.days ) %>
50
+ <%= ires_tag( path: '/image.jpg', width: 400, height: 300, expire: 7.days ) %>
42
51
  ```
43
52
 
44
53
  ### Saved directory
@@ -117,7 +126,7 @@ $ dep ensure
117
126
  # Output to a shared object.
118
127
  $ CGO_ENABLED=1 GOOS=linux go build -v -buildmode=c-shared -o shared/linux/ires.so ext/main.go
119
128
  ```
120
- ※ In the current Docker, you can build only linux environment.
129
+ ※ In the current Docker, you can build only linux environment.
121
130
  ※ If you want to build in other environments, add GCC or install Go on the host side.🙇
122
131
 
123
132
  ### 2. Start rails server
data/ext/Gopkg.lock CHANGED
@@ -2,50 +2,84 @@
2
2
 
3
3
 
4
4
  [[projects]]
5
+ digest = "1:8e47871087b94913898333f37af26732faaab30cdb41571136cf7aec9921dae7"
5
6
  name = "github.com/PuerkitoBio/purell"
6
7
  packages = ["."]
8
+ pruneopts = ""
7
9
  revision = "0bcb03f4b4d0a9428594752bd2a3b9aa0a9d4bd4"
8
10
  version = "v1.1.0"
9
11
 
10
12
  [[projects]]
11
13
  branch = "master"
14
+ digest = "1:331a419049c2be691e5ba1d24342fc77c7e767a80c666a18fd8a9f7b82419c1c"
12
15
  name = "github.com/PuerkitoBio/urlesc"
13
16
  packages = ["."]
17
+ pruneopts = ""
14
18
  revision = "de5bf2ad457846296e2031421a34e2568e304e35"
15
19
 
16
20
  [[projects]]
17
21
  branch = "master"
22
+ digest = "1:690e87555de96973ac79aae9fe51fef5e470f7e3cde3b1aa731ae01ec3f9ffe8"
18
23
  name = "github.com/goware/urlx"
19
24
  packages = ["."]
25
+ pruneopts = ""
20
26
  revision = "e22571dfbd216d3ca34207d9a1d877f38d8f051c"
21
27
 
22
28
  [[projects]]
23
29
  branch = "master"
30
+ digest = "1:74688aecdaaede7d4ea1ead4569dc5f9f8b169b3b9698470f8d107f347a7a2cd"
24
31
  name = "github.com/nfnt/resize"
25
32
  packages = ["."]
33
+ pruneopts = ""
26
34
  revision = "891127d8d1b52734debe1b3c3d7e747502b6c366"
27
35
 
28
36
  [[projects]]
37
+ digest = "1:8e8c82e661fc70a3dab1d1bb0f92b800ea32112f5926c08da9c13a46a57cc557"
29
38
  name = "github.com/oliamb/cutter"
30
39
  packages = ["."]
40
+ pruneopts = ""
31
41
  revision = "5cd9c24de6524b7251ac6b8600b0ba8f43a85963"
32
42
  version = "v0.2.0"
33
43
 
34
44
  [[projects]]
35
45
  branch = "master"
46
+ digest = "1:1418c6b5c10b5e07fb4c90a24227f6493e19ad4d31177d66458115fc47669fb5"
36
47
  name = "golang.org/x/net"
37
48
  packages = ["idna"]
49
+ pruneopts = ""
38
50
  revision = "1087133bc4af3073e18add999345c6ae75918503"
39
51
 
40
52
  [[projects]]
41
53
  branch = "master"
54
+ digest = "1:706747bb1e3f870cf0dc52459cb94324cd347142fff3b61db56c0157a5f598d0"
42
55
  name = "golang.org/x/text"
43
- packages = ["collate","collate/build","internal/colltab","internal/gen","internal/tag","internal/triegen","internal/ucd","language","secure/bidirule","transform","unicode/bidi","unicode/cldr","unicode/norm","unicode/rangetable","width"]
56
+ packages = [
57
+ "collate",
58
+ "collate/build",
59
+ "internal/colltab",
60
+ "internal/gen",
61
+ "internal/tag",
62
+ "internal/triegen",
63
+ "internal/ucd",
64
+ "language",
65
+ "secure/bidirule",
66
+ "transform",
67
+ "unicode/bidi",
68
+ "unicode/cldr",
69
+ "unicode/norm",
70
+ "unicode/rangetable",
71
+ "width",
72
+ ]
73
+ pruneopts = ""
44
74
  revision = "c01e4764d870b77f8abe5096ee19ad20d80e8075"
45
75
 
46
76
  [solve-meta]
47
77
  analyzer-name = "dep"
48
78
  analyzer-version = 1
49
- inputs-digest = "3d6ab4a2e0add98d17152b4fad7a36186d53460b01e73cab8f775b505ce51736"
79
+ input-imports = [
80
+ "github.com/goware/urlx",
81
+ "github.com/nfnt/resize",
82
+ "github.com/oliamb/cutter",
83
+ ]
50
84
  solver-name = "gps-cdcl"
51
85
  solver-version = 1
data/ext/ires/image.go CHANGED
@@ -1,57 +1,99 @@
1
1
  package ires
2
2
 
3
3
  import (
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
- "time"
15
-
16
- "github.com/nfnt/resize"
17
- "github.com/oliamb/cutter"
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
+
17
+ "github.com/nfnt/resize"
18
+ "github.com/oliamb/cutter"
18
19
  )
19
20
 
21
+ // Check expiration date
22
+ func (i *Ires) DeleteExpireImage() {
23
+ today := time.Now().Format("20060102")
24
+ dir := i.readImageDir()
25
+ files, err := ioutil.ReadDir(dir)
26
+ if err != nil {
27
+ return
28
+ }
29
+
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
+ }
38
+
39
+ // Input image type is Local or HTTP
40
+ func (i *Ires) CheckLocal() {
41
+ if strings.Index(i.URI, "http") == -1 {
42
+ i.IsLocal = true
43
+ } else {
44
+ i.IsLocal = false
45
+ }
46
+ }
20
47
 
21
48
  // Input image
22
- func inputImage(i *Ires) (image.Image, string, bool) {
49
+ func (i *Ires) inputImage() bool {
23
50
  if i.IsLocal {
24
- img, format := localImage(i.Uri)
25
- return img, format, true
26
- } else {
27
- return downloadImage(i)
51
+ img, format := localImage(i.URI)
52
+ i.InputImage = &InputImage{
53
+ Image: img,
54
+ Format: format,
55
+ URI: i.URI,
56
+ }
57
+ i.setConfig()
58
+ return true
28
59
  }
60
+ return i.downloadImage()
29
61
  }
30
62
 
31
-
32
63
  // Save http image
33
- func downloadImage(i *Ires) (image.Image, string, bool) {
34
- res, err := http.Get(i.Uri)
35
- if err != nil {
36
- panic(err)
37
- }
38
- defer res.Body.Close()
39
-
40
- header, r := copyReader(res.Body)
41
- format := formatSearch(r)
42
-
43
- img, _, err := image.Decode(io.MultiReader(header, res.Body))
44
- if err != nil {
45
- return nil, "", false
46
- }
47
- return createImage(img, i.imagePath(IMAGE_MODE_ORIGINAL), format), format, true
64
+ func (i *Ires) downloadImage() bool {
65
+ res, err := http.Get(i.URI)
66
+ if err != nil {
67
+ return false
68
+ }
69
+ defer res.Body.Close()
70
+
71
+ header, r := copyReader(res.Body)
72
+ format := formatSearch(r)
73
+
74
+ img, _, err := image.Decode(io.MultiReader(header, res.Body))
75
+ if err != nil {
76
+ return false
77
+ }
78
+
79
+ distURI := i.imageURI(true)
80
+ i.InputImage = &InputImage{
81
+ Image: img,
82
+ Format: format,
83
+ URI: distURI,
84
+ }
85
+
86
+ if createImage(img, distURI, format) {
87
+ i.setConfig()
88
+ return true
89
+ }
90
+ return false
48
91
  }
49
92
 
50
-
51
- func createImage(img image.Image, path, format string) image.Image {
93
+ func createImage(img image.Image, path, format string) bool {
52
94
  file, err := os.Create(path)
53
95
  if err != nil {
54
- panic(err)
96
+ return false
55
97
  }
56
98
  defer file.Close()
57
99
 
@@ -65,15 +107,14 @@ func createImage(img image.Image, path, format string) image.Image {
65
107
  default:
66
108
  jpeg.Encode(file, img, nil)
67
109
  }
68
- return img
110
+ return true
69
111
  }
70
112
 
71
-
72
113
  // Load image
73
114
  func localImage(uri string) (image.Image, string) {
74
115
  file, err := os.Open(uri)
75
- if err != nil{
76
- panic(err)
116
+ if err != nil {
117
+ return nil, ""
77
118
  }
78
119
  defer file.Close()
79
120
 
@@ -83,24 +124,33 @@ func localImage(uri string) (image.Image, string) {
83
124
 
84
125
  img, _, err := image.Decode(io.MultiReader(header, file))
85
126
  if err != nil {
86
- panic(err)
127
+ return nil, ""
87
128
  }
88
129
  return img, format
89
130
  }
90
131
 
132
+ // Set image config
133
+ func (i *Ires) setConfig() {
134
+ file, err := os.Open(i.InputImage.URI)
135
+ if err != nil {
136
+ panic(err)
137
+ }
138
+ defer file.Close()
139
+
140
+ conf, _, err := image.DecodeConfig(file)
141
+ if err != nil {
142
+ panic(err)
143
+ }
144
+ i.InputImage.Config = conf
145
+ }
91
146
 
92
147
  // Resizing & Cropping
93
- func resizeToCrop(i *Ires, inputImg image.Image) image.Image {
148
+ func (i *Ires) resizeToCrop() image.Image {
149
+ inputImg := i.InputImage.Image
94
150
  var outputImg image.Image
95
- var imagePath string
96
- if i.IsLocal {
97
- imagePath = i.Uri
98
- } else {
99
- imagePath = i.imagePath(IMAGE_MODE_ORIGINAL)
100
- }
101
- isAsp, conf := isValidAspectRatio(imagePath, i.Size)
151
+ isAsp, conf := i.isValidAspectRatio()
102
152
 
103
- width := i.Size.Width
153
+ width := i.Size.Width
104
154
  height := i.Size.Height
105
155
 
106
156
  if isAsp {
@@ -121,36 +171,15 @@ func resizeToCrop(i *Ires, inputImg image.Image) image.Image {
121
171
 
122
172
  // Cropping
123
173
  outputImg, _ = cutter.Crop(resizeImg, cutter.Config{
124
- Width: width,
125
- Height: height,
126
- Mode: cutter.Centered,
174
+ Width: width,
175
+ Height: height,
176
+ Mode: cutter.Centered,
127
177
  Options: cutter.Copy,
128
178
  })
129
-
130
179
  }
131
180
  return outputImg
132
181
  }
133
182
 
134
-
135
- // Check expiration date
136
- func (i *Ires) deleteExpireImage(mode int) {
137
- today := time.Now().Format("20060102")
138
- dir := i.readImageDir(mode)
139
- files, err := ioutil.ReadDir(dir)
140
- if err != nil {
141
- return
142
- }
143
-
144
- for _, file := range files {
145
- findName := file.Name()
146
- matched,_ := path.Match(today + "_*", findName)
147
- if matched {
148
- deleteImage(path.Join(dir, findName))
149
- }
150
- }
151
- }
152
-
153
-
154
183
  // Delete image
155
184
  func deleteImage(path string) {
156
185
  _, err := os.Stat(path)
@@ -161,38 +190,20 @@ func deleteImage(path string) {
161
190
  }
162
191
  }
163
192
 
164
-
165
193
  // Verify aspect ratio
166
- func isValidAspectRatio(path string, s Size) (bool, image.Config) {
167
- conf := imageConfig(path)
194
+ func (i *Ires) isValidAspectRatio() (bool, image.Config) {
195
+ conf := i.InputImage.Config
196
+ s := i.Size
168
197
  aspH := (conf.Height * s.Width) / conf.Width
169
198
  if aspH == s.Height {
170
199
  return true, conf
171
- } else {
172
- return false, conf
173
- }
174
- }
175
-
176
-
177
- // Image config
178
- func imageConfig(path string) image.Config {
179
- file, err := os.Open(path)
180
- if err != nil {
181
- panic(err)
182
- }
183
- defer file.Close()
184
-
185
- conf, _, err := image.DecodeConfig(file)
186
- if err != nil {
187
- panic(err)
188
200
  }
189
- return conf
201
+ return false, conf
190
202
  }
191
203
 
192
-
193
204
  // Select image resize mode
194
205
  func resizeMode(conf image.Config, s Size) int {
195
- srcWidth := s.Width
206
+ srcWidth := s.Width
196
207
  srcHeight := s.Height
197
208
 
198
209
  if conf.Width >= conf.Height && srcWidth >= srcHeight {
@@ -207,10 +218,9 @@ func resizeMode(conf image.Config, s Size) int {
207
218
  return 0
208
219
  }
209
220
 
210
-
211
221
  // Search image format
212
222
  // if defined, return "jpeg"
213
- func formatSearch(r io.Reader) string{
223
+ func formatSearch(r io.Reader) string {
214
224
  _, format, err := image.DecodeConfig(r)
215
225
  if err != nil {
216
226
  return "jpeg"
@@ -218,10 +228,30 @@ func formatSearch(r io.Reader) string{
218
228
  return format
219
229
  }
220
230
 
221
-
222
231
  // Copy Reader
223
232
  func copyReader(body io.Reader) (io.Reader, io.Reader) {
224
233
  header := bytes.NewBuffer(nil)
225
234
  r := io.TeeReader(body, header)
226
235
  return header, r
227
- }
236
+ }
237
+
238
+ // Valid resize type
239
+ func (i *Ires) validResizeType() bool {
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
+ }
data/ext/ires/ires.go CHANGED
@@ -1,102 +1,123 @@
1
1
  package ires
2
2
 
3
3
  import (
4
- "github.com/nfnt/resize"
5
- "github.com/oliamb/cutter"
4
+ "image"
5
+
6
+ "github.com/nfnt/resize"
7
+ "github.com/oliamb/cutter"
6
8
  )
7
9
 
10
+ type Mode int
8
11
  const (
9
- IMAGE_MODE_RESIZE int = iota
10
- IMAGE_MODE_CROP
11
- IMAGE_MODE_RESIZE_TO_CROP
12
- IMAGE_MODE_ORIGINAL
12
+ Resize Mode = iota
13
+ Crop
14
+ ResizeToCrop
13
15
  )
14
16
 
15
- type Size struct {
16
- Width, Height int
17
- }
18
-
19
- type Ires struct {
20
- Uri string
21
- Size
22
- Dir string
23
- Expire string
24
- IsLocal bool
25
- }
17
+ type ResizeType int
18
+ const (
19
+ All ResizeType = iota
20
+ Smaller
21
+ Larger
22
+ )
26
23
 
24
+ type (
25
+ // Size is ...
26
+ Size struct {
27
+ Width, Height int
28
+ }
29
+
30
+ // InputImage is ...
31
+ InputImage struct {
32
+ Image image.Image
33
+ Config image.Config
34
+ Format string
35
+ URI string
36
+ }
37
+
38
+ // Ires is ...
39
+ Ires struct {
40
+ Size
41
+ ResizeType
42
+ Mode
43
+ *InputImage
44
+ URI string
45
+ Dir string
46
+ Expire string
47
+ IsLocal bool
48
+ }
49
+ )
27
50
 
51
+ // Resize is ...
28
52
  func (i *Ires) Resize() string {
29
- // Check image type
30
- i.isLocalFile()
31
-
32
- // Delete the expiration date image
33
- i.deleteExpireImage(IMAGE_MODE_RESIZE)
34
-
35
- distPath := i.imagePath(IMAGE_MODE_RESIZE)
53
+ i.Mode = Resize
54
+ distURI := i.imageURI(false)
36
55
  // When the image exists, return the image path
37
- if isExistsImage(distPath) {
38
- return i.targetImagePath(distPath)
56
+ if isExistsImage(distURI) {
57
+ return i.targetImageURI(distURI)
39
58
  }
40
59
 
41
- inputImg, format, isImageExist := inputImage(i)
42
- if !isImageExist {
43
- return i.Uri
60
+ if !i.inputImage() {
61
+ return i.URI
44
62
  }
45
63
 
46
- outputImg := resize.Resize(uint(i.Width), uint(i.Height), inputImg, resize.Lanczos3)
47
- createImage(outputImg, distPath, format)
48
- return i.targetImagePath(distPath)
64
+ var outputImg image.Image
65
+ if i.validResizeType() {
66
+ outputImg = resize.Resize(uint(i.Width), uint(i.Height), i.InputImage.Image, resize.Lanczos3)
67
+ } else {
68
+ outputImg = i.InputImage.Image
69
+ }
70
+ createImage(outputImg, distURI, i.InputImage.Format)
71
+ return i.targetImageURI(distURI)
49
72
  }
50
73
 
74
+ // Crop is Crop ...
51
75
  func (i *Ires) Crop() string {
52
- // Check image type
53
- i.isLocalFile()
54
-
55
- // Delete the expiration date image
56
- i.deleteExpireImage(IMAGE_MODE_CROP)
57
-
58
- distPath := i.imagePath(IMAGE_MODE_CROP)
76
+ i.Mode = Crop
77
+ distURI := i.imageURI(false)
59
78
  // When the image exists, return the image path
60
- if isExistsImage(distPath) {
61
- return i.targetImagePath(distPath)
62
- }
79
+ if isExistsImage(distURI) {
80
+ return i.targetImageURI(distURI)
81
+ }
63
82
 
64
- inputImg, format, isImageExist := inputImage(i)
65
- if !isImageExist {
66
- return i.Uri
83
+ if !i.inputImage() {
84
+ return i.URI
67
85
  }
68
86
 
69
- outputImg, _ := cutter.Crop(inputImg, cutter.Config{
70
- Width: i.Width,
71
- Height: i.Height,
72
- Mode: cutter.Centered,
73
- Options: cutter.Copy,
74
- })
75
- createImage(outputImg, distPath, format)
76
-
77
- return i.targetImagePath(distPath)
87
+ var outputImg image.Image
88
+ if i.validResizeType() {
89
+ outputImg, _ = cutter.Crop(i.InputImage.Image, cutter.Config{
90
+ Width: i.Width,
91
+ Height: i.Height,
92
+ Mode: cutter.Centered,
93
+ Options: cutter.Copy,
94
+ })
95
+ } else {
96
+ outputImg = i.InputImage.Image
97
+ }
98
+ createImage(outputImg, distURI, i.InputImage.Format)
99
+ return i.targetImageURI(distURI)
78
100
  }
79
101
 
102
+ // ResizeToCrop is ...
80
103
  func (i *Ires) ResizeToCrop() string {
81
- // Check image type
82
- i.isLocalFile()
83
-
84
- // Delete the expiration date image
85
- i.deleteExpireImage(IMAGE_MODE_RESIZE_TO_CROP)
86
-
87
- distPath := i.imagePath(IMAGE_MODE_RESIZE_TO_CROP)
104
+ i.Mode = ResizeToCrop
105
+ distURI := i.imageURI(false)
88
106
  // When the image exists, return the image path
89
- if isExistsImage(distPath) {
90
- return i.targetImagePath(distPath)
107
+ if isExistsImage(distURI) {
108
+ return i.targetImageURI(distURI)
91
109
  }
92
110
 
93
- inputImg, format, isImageExist := inputImage(i)
94
- if !isImageExist {
95
- return i.Uri
111
+ if !i.inputImage() {
112
+ return i.URI
96
113
  }
97
114
 
98
- outputImg := resizeToCrop(i ,inputImg)
99
- createImage(outputImg, distPath, format)
100
-
101
- return i.targetImagePath(distPath)
115
+ var outputImg image.Image
116
+ if i.validResizeType() {
117
+ outputImg = i.resizeToCrop()
118
+ } else {
119
+ outputImg = i.InputImage.Image
120
+ }
121
+ createImage(outputImg, distURI, i.InputImage.Format)
122
+ return i.targetImageURI(distURI)
102
123
  }
data/ext/ires/uri.go CHANGED
@@ -9,48 +9,8 @@ import (
9
9
  "github.com/goware/urlx"
10
10
  )
11
11
 
12
-
13
- // Input image type is Local or HTTP
14
- func (i *Ires) isLocalFile() {
15
- if strings.Index(i.Uri, "http") == -1 {
16
- i.IsLocal = true
17
- } else {
18
- i.IsLocal = false
19
- }
20
- }
21
-
22
-
23
- // Generate image name
24
- func imageName(i *Ires, mode int) string {
25
- splitPath := strings.Split(i.Uri, "/")
26
-
27
- // ex. sample.jpg
28
- fileName := splitPath[len(splitPath)-1]
29
- // ex. .jpg
30
- ext := filepath.Ext(fileName)
31
-
32
- name := strings.Replace(fileName, ext, "", 1)
33
-
34
- extInfo := strings.Split(ext, "?")
35
- if len(extInfo) > 1 {
36
- ext = extInfo[0]
37
- name += "_" + strings.Join(extInfo[1:], "")
38
- }
39
-
40
- var prefix string
41
- switch mode {
42
- case 0: prefix = prefixSize(i.Size) + "_resize"
43
- case 1: prefix = prefixSize(i.Size) + "_crop"
44
- case 2: prefix = prefixSize(i.Size) + "_resize_to_crop"
45
- case 3: prefix = "original"
46
- }
47
-
48
- return i.Expire + "_" + name + "_" + prefix + ext
49
- }
50
-
51
-
52
12
  // Generate image path
53
- func (i *Ires) imagePath(mode int) string {
13
+ func (i *Ires) imageURI(original bool) string {
54
14
  paths := []rune(i.Dir)
55
15
  pathsLastIndex := len(paths) - 1
56
16
  lastChar := string(paths[pathsLastIndex])
@@ -61,9 +21,9 @@ func (i *Ires) imagePath(mode int) string {
61
21
 
62
22
  var oDir string
63
23
  if i.IsLocal {
64
- oDir = localPath(mode)
24
+ oDir = localPath(i.Mode)
65
25
  } else {
66
- oDir = remotePath(i)
26
+ oDir = remotePath(i.URI)
67
27
  }
68
28
 
69
29
  // Create directory
@@ -74,10 +34,43 @@ func (i *Ires) imagePath(mode int) string {
74
34
  }
75
35
  }
76
36
 
77
- name := imageName(i, mode)
37
+ name := i.imageName(original)
78
38
  return filepath.Join(oPath, name)
79
39
  }
80
40
 
41
+ // Generate image name
42
+ func (i *Ires) imageName(original bool) string {
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
+ }
81
74
 
82
75
  // Create prefix by size
83
76
  // ex. 640x480
@@ -85,45 +78,43 @@ func prefixSize(s Size) string {
85
78
  return strconv.Itoa(s.Width) + "x" + strconv.Itoa(s.Height)
86
79
  }
87
80
 
88
-
89
81
  // リサイズ済みのファイルがあれば、処理せず返す
90
82
  func isExistsImage(path string) bool {
91
83
  _, err := os.Stat(path)
92
84
  if err == nil {
93
85
  return true
94
- } else {
95
- return false
96
86
  }
87
+ return false
97
88
  }
98
89
 
99
-
100
90
  // Read directory
101
- func (i *Ires) readImageDir(mode int) string {
91
+ func (i *Ires) readImageDir() string {
102
92
  var dir string
103
93
  if i.IsLocal {
104
- dir = localPath(mode)
94
+ dir = localPath(i.Mode)
105
95
  } else {
106
- dir = remotePath(i)
96
+ dir = remotePath(i.URI)
107
97
  }
108
98
  return filepath.Join(i.Dir, dir)
109
99
  }
110
100
 
111
-
112
101
  // if local image, create ires directory
113
- func localPath(mode int) string {
102
+ func localPath(mode Mode) string {
114
103
  var dir string
115
104
  switch mode {
116
- case 0: dir = "ires/resize"
117
- case 1: dir = "ires/crop"
118
- case 2: dir = "ires/resize_to_crop"
105
+ case Resize:
106
+ dir = "ires/resize"
107
+ case Crop:
108
+ dir = "ires/crop"
109
+ case ResizeToCrop:
110
+ dir = "ires/resize_to_crop"
119
111
  }
120
112
  return dir
121
113
  }
122
114
 
123
-
124
115
  // if http image, parse URL & make directory
125
- func remotePath(i *Ires) string {
126
- u, err := urlx.Parse(i.Uri)
116
+ func remotePath(uri string) string {
117
+ u, err := urlx.Parse(uri)
127
118
  dir := []string{"ires"}
128
119
  if err != nil {
129
120
  panic(err)
@@ -136,8 +127,7 @@ func remotePath(i *Ires) string {
136
127
  return strings.Join(dir, "/")
137
128
  }
138
129
 
139
-
140
130
  // Optimize image path
141
- func (i *Ires) targetImagePath(path string) string {
142
- return strings.Replace(path, i.Dir, "", -1)
131
+ func (i *Ires) targetImageURI(uri string) string {
132
+ return strings.Replace(uri, i.Dir, "", -1)
143
133
  }
data/ext/main.go CHANGED
@@ -10,32 +10,35 @@ func init() {}
10
10
  func main() {}
11
11
 
12
12
  //export iresImagePath
13
- func iresImagePath(Uri *C.char, width, height int, Mode, Dir, Expire *C.char) *C.char {
14
- uri := C.GoString(Uri)
15
- mode := C.GoString(Mode)
16
- dir := C.GoString(Dir)
17
- expire := C.GoString(Expire)
13
+ func iresImagePath(URI *C.char, width, height, rType, mode int, Dir, Expire *C.char) *C.char {
14
+ uri := C.GoString(URI)
15
+ dir := C.GoString(Dir)
16
+ expire := C.GoString(Expire)
18
17
 
19
18
  r := &ires.Ires{
20
- Uri: uri,
21
19
  Size: ires.Size{
22
- Width: width,
20
+ Width: width,
23
21
  Height: height,
24
22
  },
25
- Dir: dir,
26
- Expire: expire,
27
- IsLocal: false,
23
+ ResizeType: ires.ResizeType(rType),
24
+ URI: uri,
25
+ Dir: dir,
26
+ Expire: expire,
28
27
  }
29
28
 
30
- var imagePath string
31
- switch mode {
32
- case "resize":
33
- imagePath = r.Resize()
34
- case "crop":
35
- imagePath = r.Crop()
36
- case "resize_to_crop":
37
- imagePath = r.ResizeToCrop()
38
- }
29
+ // If local image, True
30
+ r.CheckLocal()
31
+ // Delete the expiration date image
32
+ r.DeleteExpireImage()
39
33
 
40
- return C.CString(imagePath)
41
- }
34
+ var distURI string
35
+ switch ires.Mode(mode) {
36
+ case ires.Resize:
37
+ distURI = r.Resize()
38
+ case ires.Crop:
39
+ distURI = r.Crop()
40
+ case ires.ResizeToCrop:
41
+ distURI = r.ResizeToCrop()
42
+ }
43
+ return C.CString(distURI)
44
+ }
data/lib/ires.rb CHANGED
@@ -2,4 +2,4 @@ require 'ires/view_helper'
2
2
 
3
3
  ActiveSupport.on_load(:action_view) do
4
4
  include Ires::ViewHelper
5
- end
5
+ end
data/lib/ires/core.rb CHANGED
@@ -4,11 +4,17 @@ require 'ires/os'
4
4
  module Ires
5
5
  module Core
6
6
  extend FFI::Library
7
-
8
7
  # NOTE: ires.so is golang object
9
8
  ffi_lib File.expand_path("../../shared/#{Ires::Os.current}/ires.so", File.dirname(__FILE__))
10
-
11
9
  # resize func
12
- attach_function :iresImagePath, [:string, :int, :int, :string, :string, :string], :string
10
+ # Type:
11
+ # path: :string
12
+ # width: :int
13
+ # height: :int
14
+ # type: :int
15
+ # mode: :int
16
+ # dir: :string
17
+ # expire: :string
18
+ attach_function :iresImagePath, %i[string int int int int string string], :string
13
19
  end
14
20
  end
data/lib/ires/mode.rb ADDED
@@ -0,0 +1,7 @@
1
+ module Ires
2
+ module Mode
3
+ RESIZE = 0
4
+ CROP = 1
5
+ RESIZE_TO_CROP = 2
6
+ end
7
+ end
data/lib/ires/os.rb CHANGED
@@ -1,26 +1,25 @@
1
1
  module Ires
2
2
  module Os
3
3
  class << self
4
-
5
4
  # Reszie image directory
6
5
  # @return [none(ffi)]
7
6
  def current
8
- if ['darwin', 'linux'].include?(os)
7
+ if %w[darwin linux].include?(os)
9
8
  os
10
9
  else
11
10
  logger.fatal "Ires is not supported by this #{os}"
12
11
  nil
13
12
  end
14
13
  end
15
-
16
- private
14
+
15
+ private
17
16
 
18
17
  # Search OS
19
18
  # @return [String]
20
19
  def os
21
- @os ||= (
22
- host_os = RbConfig::CONFIG['host_os']
23
- case host_os
20
+ @os ||= begin
21
+ host_os = RbConfig::CONFIG['host_os']
22
+ case host_os
24
23
  when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
25
24
  'windows'
26
25
  when /darwin|mac os/
@@ -31,10 +30,9 @@ module Ires
31
30
  'unix'
32
31
  else
33
32
  'unknown'
33
+ end
34
34
  end
35
- )
36
35
  end
37
-
38
36
  end
39
37
  end
40
38
  end
data/lib/ires/service.rb CHANGED
@@ -1,14 +1,14 @@
1
1
  require 'ires/core'
2
2
  require 'ires/os'
3
+ require 'ires/mode'
4
+ require 'ires/type'
3
5
 
4
6
  module Ires
5
7
  class Service
6
8
  class << self
7
-
8
9
  # Resize image path
9
10
  # @return [String]
10
- def path(path:, width:, height:, mode: 'resize', expire: 30.days)
11
-
11
+ def path(path:, width:, height:, type: Type::ALL, mode: Mode::RESIZE, expire: 30.days)
12
12
  os = Ires::Os.current
13
13
  return nil if os.nil?
14
14
 
@@ -16,7 +16,7 @@ module Ires
16
16
 
17
17
  # if no image or could not find file path then perform the same action as 'image_tag'
18
18
  return nil if invalid_path?(full_path)
19
-
19
+
20
20
  expiration_date = expiration_date(expire)
21
21
  dir = image_dir
22
22
 
@@ -25,6 +25,7 @@ module Ires
25
25
  width: width,
26
26
  height: height,
27
27
  mode: mode,
28
+ type: type,
28
29
  dir: dir,
29
30
  expire: expiration_date
30
31
  }
@@ -53,28 +54,29 @@ module Ires
53
54
  # Check file or URI
54
55
  # @return [Bool]
55
56
  def invalid_path?(path)
56
- !File.exist?(path) && !path.include?("http")
57
+ !File.exist?(path) && !path.include?('http')
57
58
  end
58
59
 
59
60
  # Expiration date (default: 7.days)
60
61
  # ex. "20170101"
61
62
  # @return [String]
62
63
  def expiration_date(expire)
63
- (Date.today + expire).strftime('%Y%m%d')
64
+ (Time.zone.today + expire).strftime('%Y%m%d')
64
65
  end
65
66
 
66
67
  # Image path
67
68
  # @return [String]
68
69
  def ires_image_path(ires_element)
69
- Ires::Core.iresImagePath(
70
+ Core.iresImagePath(
70
71
  ires_element[:path],
71
72
  ires_element[:width],
72
73
  ires_element[:height],
74
+ ires_element[:type],
73
75
  ires_element[:mode],
74
76
  ires_element[:dir],
75
- ires_element[:expire])
77
+ ires_element[:expire]
78
+ )
76
79
  end
77
-
78
80
  end
79
81
  end
80
- end
82
+ end
data/lib/ires/type.rb ADDED
@@ -0,0 +1,7 @@
1
+ module Ires
2
+ module Type
3
+ ALL = 0
4
+ SMALLER = 1
5
+ LARGER = 2
6
+ end
7
+ end
data/lib/ires/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Ires
2
- VERSION = '0.2.0'
2
+ VERSION = '0.3.0'.freeze
3
3
  end
@@ -1,19 +1,26 @@
1
1
  require 'ires/core'
2
2
  require 'ires/service'
3
+ require 'ires/mode'
4
+ require 'ires/type'
3
5
  require 'action_view/helpers'
4
6
 
5
7
  module Ires
6
8
  module ViewHelper
7
-
8
9
  # Image resize
9
10
  # @return [image_tag]
10
- def ires_tag(path:, width:, height:, mode: 'resize', expire: 30.days, **option)
11
- image = Ires::Service.path(path: path, width: width, height: height, mode: mode, expire: expire)
11
+ def ires_tag(path:, width:, height:, type: Type::ALL, mode: Mode::RESIZE, expire: 30.days, **option)
12
+ image = Ires::Service.path(
13
+ path: path,
14
+ width: width,
15
+ height: height,
16
+ mode: mode,
17
+ type: type,
18
+ expire: expire
19
+ )
12
20
  return nil if image.nil?
13
21
 
14
22
  # Set image_tag
15
23
  image_tag(image, option)
16
24
  end
17
-
18
25
  end
19
- end
26
+ end
data/lib/tasks/ires.rake CHANGED
@@ -1,10 +1,10 @@
1
1
  require 'ires/os'
2
2
 
3
- desc "Build shared object"
3
+ desc 'Build shared object'
4
4
  namespace :ires do
5
5
  task :build do
6
6
  os = Ires::Os.current
7
7
  return if os.nil?
8
8
  exec "CGO_ENABLED=1 GOOS=\"#{os}\" go build -v -buildmode=c-shared -o shared/\"#{os}\"/ires.so ext/main.go"
9
9
  end
10
- end
10
+ end
data/shared/darwin/ires.h CHANGED
@@ -53,7 +53,7 @@ extern "C" {
53
53
  #endif
54
54
 
55
55
 
56
- extern char* iresImagePath(char* p0, GoInt p1, GoInt p2, char* p3, char* p4, char* p5);
56
+ extern char* iresImagePath(char* p0, GoInt p1, GoInt p2, GoInt p3, GoInt p4, char* p5, char* p6);
57
57
 
58
58
  #ifdef __cplusplus
59
59
  }
Binary file
data/shared/linux/ires.h CHANGED
@@ -1,7 +1,19 @@
1
- /* Created by "go tool cgo" - DO NOT EDIT. */
1
+ /* Code generated by cmd/cgo; DO NOT EDIT. */
2
2
 
3
3
  /* package command-line-arguments */
4
4
 
5
+
6
+ #line 1 "cgo-builtin-prolog"
7
+
8
+ #include <stddef.h> /* for ptrdiff_t below */
9
+
10
+ #ifndef GO_CGO_EXPORT_PROLOGUE_H
11
+ #define GO_CGO_EXPORT_PROLOGUE_H
12
+
13
+ typedef struct { const char *p; ptrdiff_t n; } _GoString_;
14
+
15
+ #endif
16
+
5
17
  /* Start of preamble from import "C" comments. */
6
18
 
7
19
 
@@ -38,7 +50,7 @@ typedef double _Complex GoComplex128;
38
50
  */
39
51
  typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];
40
52
 
41
- typedef struct { const char *p; GoInt n; } GoString;
53
+ typedef _GoString_ GoString;
42
54
  typedef void *GoMap;
43
55
  typedef void *GoChan;
44
56
  typedef struct { void *t; void *v; } GoInterface;
@@ -53,7 +65,7 @@ extern "C" {
53
65
  #endif
54
66
 
55
67
 
56
- extern char* iresImagePath(char* p0, GoInt p1, GoInt p2, char* p3, char* p4, char* p5);
68
+ extern char* iresImagePath(char* p0, GoInt p1, GoInt p2, GoInt p3, GoInt p4, char* p5, char* p6);
57
69
 
58
70
  #ifdef __cplusplus
59
71
  }
data/shared/linux/ires.so CHANGED
Binary file
metadata CHANGED
@@ -1,43 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ires
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - enta0701
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-26 00:00:00.000000000 Z
11
+ date: 2018-11-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: ffi
14
+ name: activesupport
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: 4.1.8
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: 4.1.8
27
27
  - !ruby/object:Gem::Dependency
28
- name: activesupport
28
+ name: ffi
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 4.1.8
33
+ version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: 4.1.8
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rails
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -1112,8 +1112,10 @@ files:
1112
1112
  - ext/vendor/golang.org/x/text/width/width.go
1113
1113
  - lib/ires.rb
1114
1114
  - lib/ires/core.rb
1115
+ - lib/ires/mode.rb
1115
1116
  - lib/ires/os.rb
1116
1117
  - lib/ires/service.rb
1118
+ - lib/ires/type.rb
1117
1119
  - lib/ires/version.rb
1118
1120
  - lib/ires/view_helper.rb
1119
1121
  - lib/tasks/ires.rake