ires 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +20 -0
  3. data/README.md +111 -0
  4. data/Rakefile +30 -0
  5. data/ext/Gopkg.lock +21 -0
  6. data/ext/Gopkg.toml +30 -0
  7. data/ext/main.go +90 -0
  8. data/ext/operate/image.go +139 -0
  9. data/ext/util/uri/uri.go +96 -0
  10. data/ext/vendor/github.com/nfnt/resize/LICENSE +13 -0
  11. data/ext/vendor/github.com/nfnt/resize/README.md +149 -0
  12. data/ext/vendor/github.com/nfnt/resize/converter.go +438 -0
  13. data/ext/vendor/github.com/nfnt/resize/converter_test.go +43 -0
  14. data/ext/vendor/github.com/nfnt/resize/filters.go +143 -0
  15. data/ext/vendor/github.com/nfnt/resize/nearest.go +318 -0
  16. data/ext/vendor/github.com/nfnt/resize/nearest_test.go +57 -0
  17. data/ext/vendor/github.com/nfnt/resize/resize.go +614 -0
  18. data/ext/vendor/github.com/nfnt/resize/resize_test.go +330 -0
  19. data/ext/vendor/github.com/nfnt/resize/thumbnail.go +55 -0
  20. data/ext/vendor/github.com/nfnt/resize/thumbnail_test.go +47 -0
  21. data/ext/vendor/github.com/nfnt/resize/ycc.go +227 -0
  22. data/ext/vendor/github.com/nfnt/resize/ycc_test.go +214 -0
  23. data/ext/vendor/github.com/oliamb/cutter/LICENSE +20 -0
  24. data/ext/vendor/github.com/oliamb/cutter/README.md +88 -0
  25. data/ext/vendor/github.com/oliamb/cutter/benchmark_test.go +54 -0
  26. data/ext/vendor/github.com/oliamb/cutter/cutter.go +183 -0
  27. data/ext/vendor/github.com/oliamb/cutter/cutter/main.go +68 -0
  28. data/ext/vendor/github.com/oliamb/cutter/cutter_test.go +267 -0
  29. data/ext/vendor/github.com/oliamb/cutter/example_test.go +35 -0
  30. data/ext/vendor/github.com/oliamb/cutter/fixtures/gopher.jpg +0 -0
  31. data/lib/ires.rb +4 -0
  32. data/lib/ires/engine.rb +7 -0
  33. data/lib/ires/service.rb +19 -0
  34. data/lib/ires/util.rb +39 -0
  35. data/lib/ires/version.rb +3 -0
  36. data/lib/ires/view_helper.rb +42 -0
  37. data/lib/tasks/ires.rake +11 -0
  38. data/shared/darwin/ires.h +64 -0
  39. data/shared/darwin/ires.so +0 -0
  40. data/shared/linux/ires.h +64 -0
  41. data/shared/linux/ires.so +0 -0
  42. metadata +154 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 66797c484af9e7c031cc342f26b4665b7f76313f
4
+ data.tar.gz: fc97bea1182999376c00f08fdfb087995dcd84cd
5
+ SHA512:
6
+ metadata.gz: a1188b7281b891486501c101d71843a7d89ac1be0e006413cdf98459693fd2a3735ac388b8d529e6459d43d298a906d18ea27c6844a8a68df27a181b0f0c17ee
7
+ data.tar.gz: 83e1fa789edf1182ccb60976889a510148c8889f51aed4561b953a7b340e583c2af67d249e10e4649a0cf822f56f3136aabae4010b0e8d2aa8e9e412b741e468
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2017 enta0701
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,111 @@
1
+ # Ires
2
+ `Ires` is image resizer gem.
3
+
4
+ ## Usage
5
+
6
+ ```erb
7
+ <!-- Usually -->
8
+ <%= ires_tag( path: "image_01.jpg", width: 90, height: 120 ) %>
9
+
10
+ <!-- Using image_tag options -->
11
+ <%= ires_tag( path: "http://example.com/image_02.jpg", width: 200, height: 200, mode: "crop", alt: "example image" ) %>
12
+ ```
13
+
14
+ ### Select mode
15
+
16
+ | info |    mode     |
17
+ |:---------------------------|:--------------------:|
18
+ | Resize | resize (default) |
19
+ | Cropping | crop |
20
+ | Rsize after Cropping | rsize_to_crop |
21
+
22
+ ### Saved directory
23
+
24
+ ```
25
+ .
26
+ └── public
27
+    └── ires
28
+    ├── crop
29
+    │   └── 300x220
30
+    │   └── image_300x220.jpg
31
+    ├── original
32
+    │   └── original
33
+    │   └── image.jpg
34
+    ├── resize
35
+    │   ├── 200x150
36
+    │   │   └── image_200x150.jpg
37
+    │   ├── 300x220
38
+    │   │   └── image_300x220.jpg
39
+     │   ├── 300x400
40
+    │   │   └── image_300x400.jpg
41
+    │   ├── 400x300
42
+    │   │   └── image_400x300.jpg
43
+    │   └── 90x120
44
+    │   └── image_90x120.jpg
45
+    └── resize_to_crop
46
+    └── 300x220
47
+    └── image_300x220.jpg
48
+ ```
49
+
50
+ `original` directory where downloaded images are saved.
51
+
52
+ ## Installation
53
+ Add this line to your application's Gemfile:
54
+
55
+ ```ruby
56
+ gem 'ires'
57
+ ```
58
+
59
+ And then execute:
60
+ ```bash
61
+ $ bundle
62
+ ```
63
+
64
+ Or install it yourself as:
65
+ ```bash
66
+ $ gem install ires
67
+ ```
68
+
69
+ ## Caution
70
+
71
+ - It works only with `linux` and `darwin` now.
72
+ - Can build only linux(.so)in this docker.
73
+
74
+
75
+ ## Development
76
+
77
+ 環境はDockerで準備しています
78
+
79
+ ```shell
80
+ $ docker build -t ires:v1 .
81
+
82
+ # コンテナに入る
83
+ $ docker run -it -v $(pwd):/go/src/github.com/endotakuya/ires -p 3000:3000 ires:v1 /bin/bash
84
+ ```
85
+
86
+ ## Gemテスト
87
+
88
+ 以下、コンテナ内の作業になります
89
+
90
+ ### 1. Go(shared objectの作成)
91
+
92
+ パッケージ管理は[dep](https://github.com/golang/dep)を使っています
93
+
94
+ ```shell
95
+ # パッケージの依存関係を解決
96
+ $ dep ensure
97
+
98
+ # shared object として出力する
99
+ $ CGO_ENABLED=1 GOOS=linux go build -v -buildmode=c-shared -o shared/linux/ires.so ext/main.go
100
+ ```
101
+ ※ 現状のDockerでは、linux環境のみbuildができます
102
+ ※ 他の環境でbuildしたい場合はGCCを追加するか、ホスト側でGoを導入してbuildしてください🙇
103
+
104
+ ### 2. Railsアプリの起動
105
+
106
+ ```shell
107
+ $ test/dummy/bin/rails s -b 0.0.0.0
108
+ ```
109
+
110
+ ## License
111
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1,30 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Ires'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ Dir.glob('lib/tasks/*.rake').each {|r| import r}
18
+ require 'bundler/gem_tasks'
19
+
20
+
21
+ require 'rake/testtask'
22
+
23
+ Rake::TestTask.new(:test) do |t|
24
+ t.libs << 'test'
25
+ t.pattern = 'test/**/*_test.rb'
26
+ t.verbose = false
27
+ end
28
+
29
+
30
+ task default: :test
@@ -0,0 +1,21 @@
1
+ # This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
2
+
3
+
4
+ [[projects]]
5
+ branch = "master"
6
+ name = "github.com/nfnt/resize"
7
+ packages = ["."]
8
+ revision = "891127d8d1b52734debe1b3c3d7e747502b6c366"
9
+
10
+ [[projects]]
11
+ name = "github.com/oliamb/cutter"
12
+ packages = ["."]
13
+ revision = "5cd9c24de6524b7251ac6b8600b0ba8f43a85963"
14
+ version = "v0.2.0"
15
+
16
+ [solve-meta]
17
+ analyzer-name = "dep"
18
+ analyzer-version = 1
19
+ inputs-digest = "555c9d2045607d7c797b9ed9663b0c2916aa91b14b6001e4119e9be49a742484"
20
+ solver-name = "gps-cdcl"
21
+ solver-version = 1
@@ -0,0 +1,30 @@
1
+
2
+ # Gopkg.toml example
3
+ #
4
+ # Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
5
+ # for detailed Gopkg.toml documentation.
6
+ #
7
+ # required = ["github.com/user/thing/cmd/thing"]
8
+ # ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
9
+ #
10
+ # [[constraint]]
11
+ # name = "github.com/user/project"
12
+ # version = "1.0.0"
13
+ #
14
+ # [[constraint]]
15
+ # name = "github.com/user/project2"
16
+ # branch = "dev"
17
+ # source = "github.com/myfork/project2"
18
+ #
19
+ # [[override]]
20
+ # name = "github.com/x/y"
21
+ # version = "2.4.0"
22
+
23
+
24
+ [[constraint]]
25
+ branch = "master"
26
+ name = "github.com/nfnt/resize"
27
+
28
+ [[constraint]]
29
+ name = "github.com/oliamb/cutter"
30
+ version = "0.2.0"
@@ -0,0 +1,90 @@
1
+ package main
2
+
3
+ import (
4
+ "C"
5
+ "strings"
6
+
7
+ "github.com/nfnt/resize"
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
+ )
18
+
19
+ func init() {}
20
+ func main() {}
21
+
22
+ //export resizeImage
23
+ func resizeImage(Uri *C.char, width, height int, Dir *C.char) *C.char {
24
+ dir := C.GoString(Dir)
25
+ uri := C.GoString(Uri)
26
+
27
+ size := []int{width, height}
28
+ path := util.NewImagePath(uri, dir, IMAGE_MODE_RESIZE, size...)
29
+
30
+ // When the image exists, return the image path
31
+ if !util.IsEmptyImage(path) {
32
+ return C.CString(strings.Replace(path, dir, "", -1))
33
+ }
34
+
35
+ inputImg, _ := operate.InputImage(uri, dir)
36
+ outputImg := resize.Resize(uint(width), uint(height), inputImg, resize.Lanczos3)
37
+
38
+ _, filePath := operate.CreateImage(outputImg, path)
39
+
40
+ fileName := strings.Replace(filePath, dir, "", -1)
41
+ return C.CString(fileName)
42
+ }
43
+
44
+ //export cropImage
45
+ func cropImage(Uri *C.char, width, height int, Dir *C.char) *C.char {
46
+ dir := C.GoString(Dir)
47
+ uri := C.GoString(Uri)
48
+
49
+ size := []int{width, height}
50
+ path := util.NewImagePath(uri, dir, IMAGE_MODE_CROP, size...)
51
+
52
+ // When the image exists, return the image path
53
+ if !util.IsEmptyImage(path) {
54
+ return C.CString(strings.Replace(path, dir, "", -1))
55
+ }
56
+
57
+ inputImg, _ := operate.InputImage(uri, dir)
58
+ outputImg, _ := cutter.Crop(inputImg, cutter.Config{
59
+ Width: width,
60
+ Height: height,
61
+ Mode: cutter.Centered,
62
+ Options: cutter.Copy,
63
+ })
64
+
65
+ _, filePath := operate.CreateImage(outputImg, path)
66
+
67
+ fileName := strings.Replace(filePath, dir, "", -1)
68
+ return C.CString(fileName)
69
+ }
70
+
71
+ //export resizeToCropImage
72
+ func resizeToCropImage(Uri *C.char, width, height int, Dir *C.char) *C.char {
73
+ dir := C.GoString(Dir)
74
+ uri := C.GoString(Uri)
75
+
76
+ size := []int{width, height}
77
+ path := util.NewImagePath(uri, dir, IMAGE_MODE_RESIZE_TO_CROP, size...)
78
+
79
+ // When the image exists, return the image path
80
+ if !util.IsEmptyImage(path) {
81
+ return C.CString(strings.Replace(path, dir, "", -1))
82
+ }
83
+
84
+ inputImg, imgPath := operate.InputImage(uri, dir)
85
+ outputImg := operate.ResizeToCrop(imgPath, size, inputImg)
86
+ _, filePath := operate.CreateImage(outputImg, path)
87
+
88
+ fileName := strings.Replace(filePath, dir, "", -1)
89
+ return C.CString(fileName)
90
+ }
@@ -0,0 +1,139 @@
1
+ package operate
2
+
3
+ import (
4
+ "image"
5
+ "image/jpeg"
6
+ "net/http"
7
+ "os"
8
+
9
+ "github.com/endotakuya/ires/ext/util/uri"
10
+ "github.com/nfnt/resize"
11
+ "github.com/oliamb/cutter"
12
+ )
13
+
14
+ // 入力画像
15
+ func InputImage(uri, dir string) (image.Image, string) {
16
+ if util.IsLocalFile(uri) {
17
+ return LocalImage(uri), uri
18
+ } else {
19
+ img, path := DownloadImage(uri, util.NewImagePath(uri, dir, 3))
20
+ return img, path
21
+ }
22
+ }
23
+
24
+ // http経由での画像を保存
25
+ func DownloadImage(uri, path string) (image.Image, string) {
26
+ res, err := http.Get(uri)
27
+ if err != nil {
28
+ panic(err)
29
+ }
30
+ defer res.Body.Close()
31
+
32
+ img, _, err := image.Decode(res.Body)
33
+ if err != nil {
34
+ panic(err)
35
+ }
36
+ return CreateImage(img, path)
37
+ }
38
+
39
+ // 画像を作成
40
+ func CreateImage(img image.Image, path string) (image.Image, string) {
41
+ file, err := os.Create(path)
42
+ if err != nil {
43
+ panic(err)
44
+ }
45
+ defer file.Close()
46
+
47
+ jpeg.Encode(file, img, nil)
48
+
49
+ return LocalImage(path), path
50
+ }
51
+
52
+ // ローカルの画像を取得
53
+ func LocalImage(uri string) image.Image {
54
+ file, err := os.Open(uri)
55
+ if err != nil{
56
+ panic(err)
57
+ }
58
+ defer file.Close()
59
+
60
+ // Decode jpeg into image.Image
61
+ img, err := jpeg.Decode(file)
62
+ if err != nil {
63
+ panic(err)
64
+ }
65
+ return img
66
+ }
67
+
68
+ // リサイズ + 切り取り
69
+ func ResizeToCrop(path string, size []int, inputImg image.Image) image.Image {
70
+ var outputImg image.Image
71
+ isAsp, conf := isValidAspectRatio(path, size)
72
+
73
+ if isAsp {
74
+ outputImg = resize.Resize(uint(size[0]), uint(size[1]), inputImg, resize.Lanczos3)
75
+ } else {
76
+ var resizeImg image.Image
77
+
78
+ // Resize
79
+ mode := resizeMode(conf, size)
80
+ switch mode {
81
+ case 1, 3:
82
+ resizeImg = resize.Resize(uint(size[0]), 0, inputImg, resize.Lanczos3)
83
+ case 2, 4:
84
+ resizeImg = resize.Resize(0, uint(size[1]), inputImg, resize.Lanczos3)
85
+ default:
86
+ resizeImg = inputImg
87
+ }
88
+
89
+ // Cropping
90
+ outputImg, _ = cutter.Crop(resizeImg, cutter.Config{
91
+ Width: size[0],
92
+ Height: size[1],
93
+ Mode: cutter.Centered,
94
+ Options: cutter.Copy,
95
+ })
96
+
97
+ }
98
+ return outputImg
99
+ }
100
+
101
+ // 変更するサイズと画像のアスペクト比が一致するかどうか
102
+ func isValidAspectRatio(path string, size []int) (bool, image.Config) {
103
+ conf := imageConfig(path)
104
+ aspH := (conf.Height * size[0]) / conf.Width
105
+ if aspH == size[1] {
106
+ return true, conf
107
+ } else {
108
+ return false, conf
109
+ }
110
+ }
111
+
112
+ // 入力画像の情報を取得
113
+ func imageConfig(path string) image.Config {
114
+ file, err := os.Open(path)
115
+ if err != nil {
116
+ panic(err)
117
+ }
118
+ defer file.Close()
119
+
120
+ conf, _, err := image.DecodeConfig(file)
121
+ if err != nil {
122
+ panic(err)
123
+ }
124
+ return conf
125
+ }
126
+
127
+ // アスペクト比の異なる画像に対するモード設定
128
+ func resizeMode(conf image.Config, size []int) int {
129
+ if conf.Width >= conf.Height && size[0] >= size[1] {
130
+ return 1
131
+ } else if conf.Width >= conf.Height && size[0] < size[1] {
132
+ return 2
133
+ } else if conf.Width < conf.Height && size[0] >= size[1] {
134
+ return 3
135
+ } else if conf.Width < conf.Height && size[0] < size[1] {
136
+ return 4
137
+ }
138
+ return 0
139
+ }