morandi 0.11.0 → 0.12.1
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/.gitignore +1 -0
- data/.rspec +1 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +24 -1
- data/README.md +4 -2
- data/lib/morandi/image-ops.rb +2 -1
- data/lib/morandi/image_processor.rb +4 -4
- data/lib/morandi/profiled_pixbuf.rb +40 -4
- data/lib/morandi/utils.rb +29 -10
- data/lib/morandi/version.rb +1 -1
- data/morandi.gemspec +3 -2
- data/spec/morandi_spec.rb +142 -79
- data/spec/spec_helper.rb +3 -1
- metadata +30 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e6da7620befd8e8fdac1a547cafbbcb0dd9e12c7d8edb5c2be0e57112e4e26ec
|
4
|
+
data.tar.gz: 2d883102edca613748f79c7aa54b6ebe7a95930b8372c2812fddde7b3762a1b9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 92dae873f4b4de40ad3e2b89d1dd4203ef48281b6390f6d59f425364aeb503b949fa6f10972fda1f1f77854dc21873cf52f1611cba38f52702d903252ec618c3
|
7
|
+
data.tar.gz: 6eb80b2a9f8b1a0fb84788a275e69f1a66c408a96337e49b33dafcc3da7ed11e80df2d74de0c9dabb1568e5bc2760b0c6ecca03c81864e55080b729034ee31ec
|
data/.gitignore
CHANGED
data/.rspec
CHANGED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.7.1
|
data/CHANGELOG.md
CHANGED
@@ -4,7 +4,30 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
5
5
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
6
6
|
|
7
|
-
## Last updated
|
7
|
+
## Last updated 10.12.2020
|
8
|
+
|
9
|
+
## [0.12.1] 10.12.2020
|
10
|
+
### Fixed
|
11
|
+
- Removed large test image
|
12
|
+
|
13
|
+
## [0.12.0] 10.12.2020
|
14
|
+
### Fixed
|
15
|
+
- Compatability with gdk_pixbuf v3.4.0+ [TECH-14001]
|
16
|
+
### Aded
|
17
|
+
- .ruby-version file
|
18
|
+
|
19
|
+
|
20
|
+
## [0.11.3] 26.06.2019
|
21
|
+
### Fixed
|
22
|
+
- Compatability with gdk_pixbuf v3.0.9+ [TECH-9065]
|
23
|
+
|
24
|
+
## [0.11.2] 21.02.2019
|
25
|
+
### Added
|
26
|
+
- While throwing Gdk::PixbufError::CorruptImage in Morandi::ProfiledPixbuf#initialize try to recover the image by saving it to a tempfile and re-read. This operation should remove all wrong markers. [TECH-7663]
|
27
|
+
|
28
|
+
## [0.11.1] 21.02.2019
|
29
|
+
### Added
|
30
|
+
- Have option to set the JPEG image compression size be a string like all the other options. [TECH-7701]
|
8
31
|
|
9
32
|
## [0.11.0] 07.12.2018
|
10
33
|
### Added
|
data/README.md
CHANGED
@@ -5,6 +5,8 @@ morandi-js.
|
|
5
5
|
|
6
6
|
## Installation
|
7
7
|
|
8
|
+
Install `liblcms2-utils` to provide the `jpgicc` command used by `Morandi::ProfiledPixbuf`
|
9
|
+
|
8
10
|
Add this line to your application's Gemfile:
|
9
11
|
|
10
12
|
gem 'morandi'
|
@@ -38,11 +40,11 @@ crop | Array[Integer,Integer,Integer,Integer] | Crop image
|
|
38
40
|
fx | String greyscale,sepia,bluetone | Apply colour filters
|
39
41
|
border-style | String square,retro | Set border style
|
40
42
|
background-style | String retro,black,white | Set border colour
|
41
|
-
quality |
|
43
|
+
quality | String '1'..'100' | Set JPG compression value, defaults to 97%
|
42
44
|
|
43
45
|
## Contributing
|
44
46
|
|
45
|
-
1. Fork it ( http://github.com
|
47
|
+
1. Fork it ( http://github.com/livelink/morandi-rb/fork )
|
46
48
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
47
49
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
48
50
|
4. Push to the branch (`git push origin my-new-feature`)
|
data/lib/morandi/image-ops.rb
CHANGED
@@ -36,7 +36,7 @@ class Crop < ImageOp
|
|
36
36
|
def call(image, pixbuf)
|
37
37
|
if @area and (not @area.width.zero?) and (not @area.height.zero?)
|
38
38
|
# NB: Cheap - fast & shares memory
|
39
|
-
|
39
|
+
GdkPixbuf::Pixbuf.new(pixbuf, @area.x, @area.y,
|
40
40
|
@area.width, @area.height)
|
41
41
|
else
|
42
42
|
pixbuf
|
@@ -223,6 +223,7 @@ class ImageBorder < ImageOp
|
|
223
223
|
|
224
224
|
case style
|
225
225
|
when 'retro'
|
226
|
+
# WARNING: CairoUtils class is not available in this gem!
|
226
227
|
CairoUtils.rounded_rectangle(cr, x, y,
|
227
228
|
img_width + x - (size*2), img_height+y-(size*2), size)
|
228
229
|
when 'square'
|
@@ -23,7 +23,7 @@ class Morandi::ImageProcessor
|
|
23
23
|
|
24
24
|
if @file.is_a?(String)
|
25
25
|
get_pixbuf
|
26
|
-
elsif @file.is_a?(
|
26
|
+
elsif @file.is_a?(GdkPixbuf::Pixbuf) or @file.is_a?(Morandi::ProfiledPixbuf)
|
27
27
|
@pb = @file
|
28
28
|
@scale = 1.0
|
29
29
|
end
|
@@ -72,13 +72,13 @@ class Morandi::ImageProcessor
|
|
72
72
|
end
|
73
73
|
|
74
74
|
def write_to_jpeg(fn, quality = nil)
|
75
|
-
quality ||= options.fetch(
|
76
|
-
@pb.save(fn, 'jpeg', quality: quality)
|
75
|
+
quality ||= options.fetch('quality', '97')
|
76
|
+
@pb.save(fn, 'jpeg', quality: quality.to_s)
|
77
77
|
end
|
78
78
|
|
79
79
|
protected
|
80
80
|
def get_pixbuf
|
81
|
-
_, width, height =
|
81
|
+
_, width, height = GdkPixbuf::Pixbuf.get_file_info(@file)
|
82
82
|
|
83
83
|
if @scale_to
|
84
84
|
@pb = Morandi::ProfiledPixbuf.new(@file, @scale_to, @scale_to, @local_options)
|
@@ -1,17 +1,26 @@
|
|
1
1
|
require 'gdk_pixbuf2'
|
2
2
|
|
3
|
-
class Morandi::ProfiledPixbuf <
|
3
|
+
class Morandi::ProfiledPixbuf < GdkPixbuf::Pixbuf
|
4
4
|
def valid_jpeg?(filename)
|
5
5
|
return false unless File.exist?(filename)
|
6
6
|
return false unless File.size(filename) > 0
|
7
7
|
|
8
|
-
type, _, _ =
|
8
|
+
type, _, _ = GdkPixbuf::Pixbuf.get_file_info(filename)
|
9
9
|
|
10
10
|
type && type.name.eql?('jpeg')
|
11
11
|
rescue
|
12
12
|
false
|
13
13
|
end
|
14
14
|
|
15
|
+
def self.from_string(string, loader: nil, chunk_size: 4096)
|
16
|
+
loader ||= GdkPixbuf::PixbufLoader.new
|
17
|
+
((string.bytesize + chunk_size - 1) / chunk_size).times do |i|
|
18
|
+
loader.write(string.byteslice(i * chunk_size, chunk_size))
|
19
|
+
end
|
20
|
+
loader.close
|
21
|
+
loader.pixbuf
|
22
|
+
end
|
23
|
+
|
15
24
|
def self.default_icc_path(path)
|
16
25
|
"#{path}.icc.jpg"
|
17
26
|
end
|
@@ -29,13 +38,40 @@ class Morandi::ProfiledPixbuf < Gdk::Pixbuf
|
|
29
38
|
end
|
30
39
|
end
|
31
40
|
|
32
|
-
|
41
|
+
# TODO: This is to fix some deprecation warnings. This needs refactoring.
|
42
|
+
# All can be implemented without having to hack on the PixBuff gem.
|
43
|
+
case args.size
|
44
|
+
when 1
|
45
|
+
super(file: args.first)
|
46
|
+
when 3
|
47
|
+
super(path: args[0], width: args[1], height: args[2])
|
48
|
+
else
|
49
|
+
super(*args)
|
50
|
+
end
|
51
|
+
rescue GdkPixbuf::PixbufError::CorruptImage => e
|
52
|
+
if args[0].is_a?(String) && defined? Tempfile
|
53
|
+
temp = Tempfile.new
|
54
|
+
pixbuf = self.class.from_string(File.read(args[0]))
|
55
|
+
pixbuf.save(temp.path, 'jpeg')
|
56
|
+
args[0] = temp.path
|
57
|
+
|
58
|
+
if args.size == 1
|
59
|
+
super file: args.first
|
60
|
+
else
|
61
|
+
super(*args)
|
62
|
+
end
|
63
|
+
|
64
|
+
temp.close
|
65
|
+
temp.unlink
|
66
|
+
else
|
67
|
+
throw e
|
68
|
+
end
|
33
69
|
end
|
34
70
|
|
35
71
|
|
36
72
|
protected
|
37
73
|
def suitable_for_jpegicc?
|
38
|
-
type, _, _ =
|
74
|
+
type, _, _ = GdkPixbuf::Pixbuf.get_file_info(@file)
|
39
75
|
|
40
76
|
type && type.name.eql?('jpeg')
|
41
77
|
end
|
data/lib/morandi/utils.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'gdk_pixbuf2'
|
2
|
+
|
1
3
|
module Morandi
|
2
4
|
module Utils
|
3
5
|
module_function
|
@@ -45,7 +47,13 @@ module Morandi
|
|
45
47
|
def apply_crop(pixbuf, x, y, w, h, fill_col = 0xffffffff)
|
46
48
|
if (x < 0) or (y < 0) || ((x+w) > pixbuf.width) || ((y+h) > pixbuf.height)
|
47
49
|
#tw, th = [w-x,w].max, [h-y,h].max
|
48
|
-
base_pixbuf =
|
50
|
+
base_pixbuf = GdkPixbuf::Pixbuf.new(
|
51
|
+
colorspace: GdkPixbuf::Colorspace::RGB,
|
52
|
+
has_alpha: false,
|
53
|
+
bits_per_sample: 8,
|
54
|
+
width: w,
|
55
|
+
height: h
|
56
|
+
)
|
49
57
|
base_pixbuf.fill!(fill_col)
|
50
58
|
dest_x = [x, 0].min
|
51
59
|
dest_y = [y, 0].min
|
@@ -78,10 +86,18 @@ module Morandi
|
|
78
86
|
if copy_h + paste_y > base_pixbuf.height
|
79
87
|
copy_h = base_pixbuf.height - paste_y
|
80
88
|
end
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
89
|
+
base_pixbuf.composite! pixbuf, {
|
90
|
+
dest_x: paste_x,
|
91
|
+
dest_y: paste_y,
|
92
|
+
dest_width: copy_w,
|
93
|
+
dest_height: copy_h,
|
94
|
+
offset_x: paste_x - offset_x,
|
95
|
+
offset_y: paste_y - offset_y,
|
96
|
+
scale_x: 1,
|
97
|
+
scale_y: 1,
|
98
|
+
interpolation_type: :hyper,
|
99
|
+
overall_alpha: 255
|
100
|
+
}
|
85
101
|
pixbuf = base_pixbuf
|
86
102
|
else
|
87
103
|
x = constrain(x, 0, pixbuf.width)
|
@@ -89,15 +105,19 @@ module Morandi
|
|
89
105
|
w = constrain(w, 1, pixbuf.width - x)
|
90
106
|
h = constrain(h, 1, pixbuf.height - y)
|
91
107
|
#p [pixbuf, x, y, w, h]
|
92
|
-
pixbuf =
|
108
|
+
pixbuf = pixbuf.subpixbuf(x, y, w, h)
|
93
109
|
end
|
94
110
|
pixbuf
|
95
111
|
end
|
96
112
|
end
|
97
113
|
end
|
98
114
|
|
99
|
-
class
|
100
|
-
|
115
|
+
class GdkPixbuf::Pixbuf
|
116
|
+
unless defined?(::GdkPixbuf::Pixbuf::InterpType)
|
117
|
+
InterpType = GdkPixbuf::InterpType
|
118
|
+
end
|
119
|
+
|
120
|
+
def scale_max(max_size, interp = GdkPixbuf::Pixbuf::InterpType::BILINEAR, max_scale = 1.0)
|
101
121
|
mul = (max_size / [width,height].max.to_f)
|
102
122
|
mul = [max_scale = 1.0,mul].min
|
103
123
|
scale(width * mul, height * mul, interp)
|
@@ -106,7 +126,7 @@ end
|
|
106
126
|
|
107
127
|
class Cairo::ImageSurface
|
108
128
|
def to_pixbuf
|
109
|
-
loader =
|
129
|
+
loader = GdkPixbuf::PixbufLoader.new
|
110
130
|
io = StringIO.new
|
111
131
|
write_to_png(io)
|
112
132
|
io.rewind
|
@@ -114,4 +134,3 @@ class Cairo::ImageSurface
|
|
114
134
|
loader.pixbuf
|
115
135
|
end
|
116
136
|
end
|
117
|
-
|
data/lib/morandi/version.rb
CHANGED
data/morandi.gemspec
CHANGED
@@ -19,14 +19,15 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
21
|
spec.add_dependency "gtk2"
|
22
|
-
spec.add_dependency "gdk_pixbuf2"
|
22
|
+
spec.add_dependency "gdk_pixbuf2", "~> 3.4.0"
|
23
23
|
spec.add_dependency "cairo"
|
24
24
|
spec.add_dependency "pixbufutils"
|
25
25
|
spec.add_dependency "redeye"
|
26
26
|
spec.add_dependency "pango"
|
27
27
|
spec.add_dependency "colorscore"
|
28
28
|
|
29
|
-
spec.add_development_dependency "bundler"
|
29
|
+
spec.add_development_dependency "bundler"
|
30
|
+
spec.add_development_dependency "pry"
|
30
31
|
spec.add_development_dependency "rake"
|
31
32
|
spec.add_development_dependency "rspec"
|
32
33
|
end
|
data/spec/morandi_spec.rb
CHANGED
@@ -1,145 +1,208 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'fileutils'
|
1
4
|
require 'morandi'
|
2
5
|
|
3
|
-
RSpec.describe Morandi,
|
4
|
-
context
|
5
|
-
it
|
6
|
-
Morandi.process(
|
6
|
+
RSpec.describe Morandi, '#process' do
|
7
|
+
context 'in command mode' do
|
8
|
+
it 'should create ouptut' do
|
9
|
+
Morandi.process('sample/sample.jpg', {}, out = 'sample/out_plain.jpg')
|
7
10
|
expect(File.exist?(out))
|
8
11
|
end
|
9
12
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
13
|
+
context "with a big image and a bigger cropped area to fill" do
|
14
|
+
it 'should create ouptut' do
|
15
|
+
settings = {
|
16
|
+
"crop"=>"0,477,15839,18804",
|
17
|
+
"angle"=>90,
|
18
|
+
"fx"=>"colour",
|
19
|
+
"straighten"=>0.0,
|
20
|
+
"gamma"=>0.98,
|
21
|
+
"redeye"=>[]
|
22
|
+
}
|
23
|
+
|
24
|
+
Morandi.process('sample/sample.jpg', settings, out = 'sample/out_crop_glitch_image.jpg')
|
25
|
+
expect(File.exist?(out))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should do rotation of images' do
|
30
|
+
original = GdkPixbuf::Pixbuf.get_file_info('sample/sample.jpg')
|
31
|
+
Morandi.process('sample/sample.jpg', {
|
32
|
+
'angle' => 90
|
33
|
+
}, out = 'sample/out_rotate90.jpg')
|
15
34
|
expect(File.exist?(out))
|
16
|
-
_,
|
17
|
-
expect(original[1]).to eq(
|
18
|
-
expect(original[2]).to eq(
|
35
|
+
_, width, height = GdkPixbuf::Pixbuf.get_file_info(out)
|
36
|
+
expect(original[1]).to eq(height)
|
37
|
+
expect(original[2]).to eq(width)
|
19
38
|
end
|
20
39
|
|
21
|
-
it
|
22
|
-
pixbuf =
|
40
|
+
it 'should accept pixbufs as an argument' do
|
41
|
+
pixbuf = GdkPixbuf::Pixbuf.new(file: 'sample/sample.jpg')
|
23
42
|
pro = Morandi::ImageProcessor.new(pixbuf, {}, {})
|
24
43
|
pro.process!
|
25
44
|
expect(pixbuf.width).to eq(pro.result.width)
|
26
45
|
end
|
27
46
|
|
28
|
-
it
|
29
|
-
Morandi.process(
|
30
|
-
|
31
|
-
|
47
|
+
it 'should do cropping of images' do
|
48
|
+
Morandi.process('sample/sample.jpg', {
|
49
|
+
'crop' => [10, 10, 300, 300]
|
50
|
+
}, out = 'sample/out_crop.jpg')
|
32
51
|
expect(File.exist?(out))
|
33
|
-
_,
|
34
|
-
expect(
|
35
|
-
expect(
|
52
|
+
_, width, height = GdkPixbuf::Pixbuf.get_file_info(out)
|
53
|
+
expect(width).to eq(300)
|
54
|
+
expect(height).to eq(300)
|
36
55
|
end
|
37
56
|
|
38
|
-
it
|
57
|
+
it 'should use user supplied path.icc' do
|
39
58
|
src = 'sample/sample.jpg'
|
40
59
|
icc = '/tmp/this-is-secure-thing.jpg'
|
41
60
|
default_icc = Morandi::ImageProcessor.default_icc_path(src)
|
42
61
|
out = 'sample/out_icc.jpg'
|
43
|
-
|
44
|
-
Morandi.process(src, {
|
62
|
+
FileUtils.rm_f(default_icc)
|
63
|
+
Morandi.process(src, {}, out, 'path.icc' => icc)
|
45
64
|
expect(File).to exist(icc)
|
46
65
|
expect(File).not_to exist(default_icc)
|
47
66
|
end
|
48
67
|
|
49
|
-
it
|
68
|
+
it 'should ignore user supplied path.icc' do
|
50
69
|
src = 'sample/sample.jpg'
|
51
70
|
icc = '/tmp/this-is-insecure-thing.jpg'
|
52
71
|
default_icc = Morandi::ImageProcessor.default_icc_path(src)
|
53
|
-
|
54
|
-
|
72
|
+
FileUtils.rm_f(icc)
|
73
|
+
FileUtils.rm_f(default_icc)
|
55
74
|
out = 'sample/out_icc.jpg'
|
56
75
|
Morandi.process(src, { 'path.icc' => icc, 'output.max' => 200 }, out)
|
57
76
|
expect(File).not_to exist(icc)
|
58
77
|
expect(File).to exist(default_icc)
|
59
78
|
end
|
60
79
|
|
61
|
-
it
|
62
|
-
Morandi.process(
|
63
|
-
|
64
|
-
|
80
|
+
it 'should do cropping of images with a string' do
|
81
|
+
Morandi.process('sample/sample.jpg', {
|
82
|
+
'crop' => '10,10,300,300'
|
83
|
+
}, out = 'sample/out_crop.jpg')
|
84
|
+
expect(File.exist?(out))
|
85
|
+
_, width, height = GdkPixbuf::Pixbuf.get_file_info(out)
|
86
|
+
expect(width).to eq(300)
|
87
|
+
expect(height).to eq(300)
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'should reduce the size of images' do
|
91
|
+
Morandi.process('sample/sample.jpg', {
|
92
|
+
'output.max' => 200
|
93
|
+
}, out = 'sample/out_reduce.jpg')
|
65
94
|
expect(File.exist?(out))
|
66
|
-
_,
|
67
|
-
expect(
|
68
|
-
expect(
|
95
|
+
_, width, height = GdkPixbuf::Pixbuf.get_file_info(out)
|
96
|
+
expect(width).to be <= 200
|
97
|
+
expect(height).to be <= 200
|
69
98
|
end
|
70
99
|
|
71
|
-
it
|
72
|
-
Morandi.process(
|
73
|
-
|
74
|
-
|
100
|
+
it 'should reduce the straighten images' do
|
101
|
+
Morandi.process('sample/sample.jpg', {
|
102
|
+
'straighten' => 5
|
103
|
+
}, out = 'sample/out_straighten.jpg')
|
75
104
|
expect(File.exist?(out))
|
76
|
-
_,
|
77
|
-
expect(
|
78
|
-
expect(h).to be <= 200
|
105
|
+
info, _, _ = GdkPixbuf::Pixbuf.get_file_info(out)
|
106
|
+
expect(info.name).to eq('jpeg')
|
79
107
|
end
|
80
108
|
|
81
|
-
it
|
82
|
-
Morandi.process(
|
83
|
-
|
84
|
-
|
109
|
+
it 'should reduce the gamma correct images' do
|
110
|
+
Morandi.process('sample/sample.jpg', {
|
111
|
+
'gamma' => 1.2
|
112
|
+
}, out = 'sample/out_gamma.jpg')
|
85
113
|
expect(File.exist?(out))
|
86
|
-
_,
|
87
|
-
expect(
|
114
|
+
info, _, _ = GdkPixbuf::Pixbuf.get_file_info(out)
|
115
|
+
expect(info.name).to eq('jpeg')
|
88
116
|
end
|
89
117
|
|
90
|
-
it
|
91
|
-
Morandi.process(
|
92
|
-
|
93
|
-
|
118
|
+
it 'should reduce the size of images' do
|
119
|
+
Morandi.process('sample/sample.jpg', {
|
120
|
+
'fx' => 'sepia'
|
121
|
+
}, out = 'sample/out_sepia.jpg')
|
94
122
|
expect(File.exist?(out))
|
95
|
-
_,
|
96
|
-
expect(
|
123
|
+
info, _, _ = GdkPixbuf::Pixbuf.get_file_info(out)
|
124
|
+
expect(info.name).to eq('jpeg')
|
97
125
|
end
|
98
126
|
|
99
|
-
it
|
100
|
-
Morandi.process(
|
101
|
-
|
102
|
-
|
127
|
+
it 'should output at the specified size' do
|
128
|
+
Morandi.process('sample/sample.jpg', {
|
129
|
+
'output.width' => 300,
|
130
|
+
'output.height' => 200,
|
131
|
+
'image.auto-crop' => true,
|
132
|
+
'output.limit' => true
|
133
|
+
}, out = 'sample/out_at_size.jpg')
|
103
134
|
expect(File.exist?(out))
|
104
|
-
|
105
|
-
expect(
|
135
|
+
info, width, height = GdkPixbuf::Pixbuf.get_file_info(out)
|
136
|
+
expect(info.name).to eq('jpeg')
|
137
|
+
expect(width).to be <= 300
|
138
|
+
expect(height).to be <= 200
|
106
139
|
end
|
107
140
|
|
108
|
-
it
|
109
|
-
Morandi.process(
|
110
|
-
'
|
111
|
-
|
112
|
-
'image.auto-crop' => true,
|
113
|
-
'output.limit' => true
|
114
|
-
}, out="sample/out_at_size.jpg")
|
141
|
+
it 'should blur the image' do
|
142
|
+
Morandi.process('sample/sample.jpg', {
|
143
|
+
'sharpen' => -3
|
144
|
+
}, out = 'sample/out_blur.jpg')
|
115
145
|
expect(File.exist?(out))
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'should apply a border and maintain the target size' do
|
149
|
+
Morandi.process('sample/sample.jpg', {
|
150
|
+
'border-style' => 'square',
|
151
|
+
'background-style' => 'dominant',
|
152
|
+
'border-size-mm' => 5,
|
153
|
+
'output.width' => 800,
|
154
|
+
'output.height' => 650
|
155
|
+
}, out = 'sample/out_border.jpg')
|
156
|
+
expect(File.exist?(out))
|
157
|
+
|
158
|
+
info, width, height = GdkPixbuf::Pixbuf.get_file_info(out)
|
159
|
+
expect(info.name).to eq('jpeg')
|
160
|
+
expect(width).to eq 800
|
161
|
+
expect(height).to eq 650
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'should apply multiple transformations' do
|
165
|
+
Morandi.process('sample/sample.jpg', {
|
166
|
+
'brighten' => 5,
|
167
|
+
'contrast' => 5,
|
168
|
+
'sharpen' => 2,
|
169
|
+
'fx' => 'greyscale',
|
170
|
+
'border-style' => 'solid',
|
171
|
+
'background-style' => '#00FF00',
|
172
|
+
'crop' => [50, 0, 750, 650],
|
173
|
+
'output.width' => 300,
|
174
|
+
'output.height' => 260,
|
175
|
+
'output.limit' => true
|
176
|
+
}, out = 'sample/out_various.jpg')
|
177
|
+
expect(File.exist?(out))
|
178
|
+
|
179
|
+
info, width, height = GdkPixbuf::Pixbuf.get_file_info(out)
|
180
|
+
expect(info.name).to eq('jpeg')
|
181
|
+
expect(width).to eq 300
|
182
|
+
expect(height).to eq 260
|
120
183
|
end
|
121
184
|
end
|
122
185
|
|
123
186
|
context 'with increasing quality settings' do
|
124
187
|
let(:max_quality_file_size) do
|
125
|
-
Morandi.process(
|
126
|
-
File.size(
|
188
|
+
Morandi.process('sample/sample.jpg', { 'quality' => 100 }, 'sample/out-100.jpg')
|
189
|
+
File.size('sample/out-100.jpg')
|
127
190
|
end
|
128
191
|
|
129
192
|
let(:default_of_97_quality) do
|
130
|
-
Morandi.process(
|
131
|
-
File.size(
|
193
|
+
Morandi.process('sample/sample.jpg', {}, 'sample/out-97.jpg')
|
194
|
+
File.size('sample/out-97.jpg')
|
132
195
|
end
|
133
196
|
|
134
197
|
let(:quality_of_40_by_options_args) do
|
135
|
-
Morandi.process(
|
136
|
-
File.size(
|
198
|
+
Morandi.process('sample/sample.jpg', { 'quality' => 40 }, 'sample/out-40.jpg')
|
199
|
+
File.size('sample/out-40.jpg')
|
137
200
|
end
|
138
201
|
|
139
202
|
# Sort the output files' sizes and expect them to match to quality order
|
140
|
-
it
|
141
|
-
|
142
|
-
|
203
|
+
it 'creates files of increasing size' do
|
204
|
+
created_file_sizes = [default_of_97_quality, max_quality_file_size, quality_of_40_by_options_args].sort
|
205
|
+
expect(created_file_sizes).to eq([quality_of_40_by_options_args, default_of_97_quality, max_quality_file_size])
|
143
206
|
end
|
144
207
|
end
|
145
208
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -4,8 +4,10 @@
|
|
4
4
|
# loaded once.
|
5
5
|
#
|
6
6
|
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
+
|
8
|
+
require "pry"
|
9
|
+
|
7
10
|
RSpec.configure do |config|
|
8
|
-
config.treat_symbols_as_metadata_keys_with_true_values = true
|
9
11
|
config.run_all_when_everything_filtered = true
|
10
12
|
config.filter_run :focus
|
11
13
|
|
metadata
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: morandi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- |+
|
8
8
|
Geoff Youngs
|
9
9
|
|
10
10
|
|
11
|
-
autorequire:
|
11
|
+
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date:
|
14
|
+
date: 2020-12-10 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: gtk2
|
@@ -31,16 +31,16 @@ dependencies:
|
|
31
31
|
name: gdk_pixbuf2
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
33
33
|
requirements:
|
34
|
-
- - "
|
34
|
+
- - "~>"
|
35
35
|
- !ruby/object:Gem::Version
|
36
|
-
version:
|
36
|
+
version: 3.4.0
|
37
37
|
type: :runtime
|
38
38
|
prerelease: false
|
39
39
|
version_requirements: !ruby/object:Gem::Requirement
|
40
40
|
requirements:
|
41
|
-
- - "
|
41
|
+
- - "~>"
|
42
42
|
- !ruby/object:Gem::Version
|
43
|
-
version:
|
43
|
+
version: 3.4.0
|
44
44
|
- !ruby/object:Gem::Dependency
|
45
45
|
name: cairo
|
46
46
|
requirement: !ruby/object:Gem::Requirement
|
@@ -115,16 +115,30 @@ dependencies:
|
|
115
115
|
name: bundler
|
116
116
|
requirement: !ruby/object:Gem::Requirement
|
117
117
|
requirements:
|
118
|
-
- - "
|
118
|
+
- - ">="
|
119
119
|
- !ruby/object:Gem::Version
|
120
|
-
version: '
|
120
|
+
version: '0'
|
121
121
|
type: :development
|
122
122
|
prerelease: false
|
123
123
|
version_requirements: !ruby/object:Gem::Requirement
|
124
124
|
requirements:
|
125
|
-
- - "
|
125
|
+
- - ">="
|
126
126
|
- !ruby/object:Gem::Version
|
127
|
-
version: '
|
127
|
+
version: '0'
|
128
|
+
- !ruby/object:Gem::Dependency
|
129
|
+
name: pry
|
130
|
+
requirement: !ruby/object:Gem::Requirement
|
131
|
+
requirements:
|
132
|
+
- - ">="
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: '0'
|
135
|
+
type: :development
|
136
|
+
prerelease: false
|
137
|
+
version_requirements: !ruby/object:Gem::Requirement
|
138
|
+
requirements:
|
139
|
+
- - ">="
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
128
142
|
- !ruby/object:Gem::Dependency
|
129
143
|
name: rake
|
130
144
|
requirement: !ruby/object:Gem::Requirement
|
@@ -162,6 +176,7 @@ extra_rdoc_files: []
|
|
162
176
|
files:
|
163
177
|
- ".gitignore"
|
164
178
|
- ".rspec"
|
179
|
+
- ".ruby-version"
|
165
180
|
- CHANGELOG.md
|
166
181
|
- Gemfile
|
167
182
|
- LICENSE.txt
|
@@ -182,7 +197,7 @@ homepage: ''
|
|
182
197
|
licenses:
|
183
198
|
- MIT
|
184
199
|
metadata: {}
|
185
|
-
post_install_message:
|
200
|
+
post_install_message:
|
186
201
|
rdoc_options: []
|
187
202
|
require_paths:
|
188
203
|
- lib
|
@@ -197,11 +212,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
197
212
|
- !ruby/object:Gem::Version
|
198
213
|
version: '0'
|
199
214
|
requirements: []
|
200
|
-
|
201
|
-
|
202
|
-
signing_key:
|
215
|
+
rubygems_version: 3.1.2
|
216
|
+
signing_key:
|
203
217
|
specification_version: 4
|
204
218
|
summary: Simple Image Edits
|
205
219
|
test_files:
|
206
220
|
- spec/morandi_spec.rb
|
207
221
|
- spec/spec_helper.rb
|
222
|
+
...
|