morandi 0.10.3 → 0.12.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 +5 -5
- data/.gitignore +1 -0
- data/.rspec +1 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +30 -0
- data/README.md +4 -2
- data/lib/morandi.rb +0 -1
- data/lib/morandi/image-ops.rb +2 -1
- data/lib/morandi/image_processor.rb +5 -5
- 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/sample/100_mb_image.jpg +0 -0
- data/spec/morandi_spec.rb +156 -70
- data/spec/spec_helper.rb +3 -1
- metadata +32 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 1d1a30842ccacd85b3680f80c8d4a68c52dd96edcf5136963a73c9049089ab5b
|
4
|
+
data.tar.gz: 9b2ee86c53d336481c377834baef371d16bba4886a0272c61211077ab8cb8da6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cdb7f1ff080d549101e49c030c76dda02f433e9d4e7824e1abb6ebdf149268c0e406334bac8ea6848a7008293ceb8fd43f43d605623b771989fddc6df4faccd5
|
7
|
+
data.tar.gz: c7a00a804bb12717fba9c3e613ba813d1213d64934b8c2e3a21b9d1b10367d13f9b33f8fe0677b6b9e626d0bbf65806071286e7c6e3b6a57db6d4cfef68c4295
|
data/.gitignore
CHANGED
data/.rspec
CHANGED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.7.1
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# Changelog
|
2
|
+
All notable changes to this project will be documented in this file.
|
3
|
+
|
4
|
+
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
5
|
+
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
6
|
+
|
7
|
+
## Last updated 10.12.2020
|
8
|
+
|
9
|
+
## [0.12.0] 10.12.2020
|
10
|
+
### Fixed
|
11
|
+
- Compatability with gdk_pixbuf v3.4.0+ [TECH-14001]
|
12
|
+
### Aded
|
13
|
+
- .ruby-version file
|
14
|
+
|
15
|
+
|
16
|
+
## [0.11.3] 26.06.2019
|
17
|
+
### Fixed
|
18
|
+
- Compatability with gdk_pixbuf v3.0.9+ [TECH-9065]
|
19
|
+
|
20
|
+
## [0.11.2] 21.02.2019
|
21
|
+
### Added
|
22
|
+
- 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]
|
23
|
+
|
24
|
+
## [0.11.1] 21.02.2019
|
25
|
+
### Added
|
26
|
+
- Have option to set the JPEG image compression size be a string like all the other options. [TECH-7701]
|
27
|
+
|
28
|
+
## [0.11.0] 07.12.2018
|
29
|
+
### Added
|
30
|
+
- Added option to set the JPEG image compression size [104324]
|
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
|
-
|
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.rb
CHANGED
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
|
@@ -71,13 +71,14 @@ class Morandi::ImageProcessor
|
|
71
71
|
pb.save(fn, 'png')
|
72
72
|
end
|
73
73
|
|
74
|
-
def write_to_jpeg(fn, quality =
|
75
|
-
|
74
|
+
def write_to_jpeg(fn, quality = nil)
|
75
|
+
quality ||= options.fetch('quality', '97')
|
76
|
+
@pb.save(fn, 'jpeg', quality: quality.to_s)
|
76
77
|
end
|
77
78
|
|
78
79
|
protected
|
79
80
|
def get_pixbuf
|
80
|
-
_, width, height =
|
81
|
+
_, width, height = GdkPixbuf::Pixbuf.get_file_info(@file)
|
81
82
|
|
82
83
|
if @scale_to
|
83
84
|
@pb = Morandi::ProfiledPixbuf.new(@file, @scale_to, @scale_to, @local_options)
|
@@ -242,4 +243,3 @@ protected
|
|
242
243
|
end
|
243
244
|
|
244
245
|
end
|
245
|
-
|
@@ -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
|
Binary file
|
data/spec/morandi_spec.rb
CHANGED
@@ -1,122 +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/100_mb_image.jpg', settings, out = 'sample/out_100_mb_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')
|
94
|
+
expect(File.exist?(out))
|
95
|
+
_, width, height = GdkPixbuf::Pixbuf.get_file_info(out)
|
96
|
+
expect(width).to be <= 200
|
97
|
+
expect(height).to be <= 200
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'should reduce the straighten images' do
|
101
|
+
Morandi.process('sample/sample.jpg', {
|
102
|
+
'straighten' => 5
|
103
|
+
}, out = 'sample/out_straighten.jpg')
|
104
|
+
expect(File.exist?(out))
|
105
|
+
info, _, _ = GdkPixbuf::Pixbuf.get_file_info(out)
|
106
|
+
expect(info.name).to eq('jpeg')
|
107
|
+
end
|
108
|
+
|
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')
|
65
113
|
expect(File.exist?(out))
|
66
|
-
_,
|
67
|
-
expect(
|
68
|
-
expect(h).to eq(300)
|
114
|
+
info, _, _ = GdkPixbuf::Pixbuf.get_file_info(out)
|
115
|
+
expect(info.name).to eq('jpeg')
|
69
116
|
end
|
70
117
|
|
71
|
-
it
|
72
|
-
Morandi.process(
|
73
|
-
|
74
|
-
|
118
|
+
it 'should reduce the size of images' do
|
119
|
+
Morandi.process('sample/sample.jpg', {
|
120
|
+
'fx' => 'sepia'
|
121
|
+
}, out = 'sample/out_sepia.jpg')
|
75
122
|
expect(File.exist?(out))
|
76
|
-
_,
|
77
|
-
expect(
|
78
|
-
expect(h).to be <= 200
|
123
|
+
info, _, _ = GdkPixbuf::Pixbuf.get_file_info(out)
|
124
|
+
expect(info.name).to eq('jpeg')
|
79
125
|
end
|
80
126
|
|
81
|
-
it
|
82
|
-
Morandi.process(
|
83
|
-
|
84
|
-
|
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')
|
85
134
|
expect(File.exist?(out))
|
86
|
-
|
87
|
-
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
|
88
139
|
end
|
89
140
|
|
90
|
-
it
|
91
|
-
Morandi.process(
|
92
|
-
'
|
93
|
-
}, out=
|
141
|
+
it 'should blur the image' do
|
142
|
+
Morandi.process('sample/sample.jpg', {
|
143
|
+
'sharpen' => -3
|
144
|
+
}, out = 'sample/out_blur.jpg')
|
94
145
|
expect(File.exist?(out))
|
95
|
-
_,w,h = Gdk::Pixbuf.get_file_info(out)
|
96
|
-
expect(_.name).to eq('jpeg')
|
97
146
|
end
|
98
147
|
|
99
|
-
it
|
100
|
-
Morandi.process(
|
101
|
-
'
|
102
|
-
|
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')
|
103
156
|
expect(File.exist?(out))
|
104
|
-
|
105
|
-
|
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
|
106
162
|
end
|
107
163
|
|
108
|
-
it
|
109
|
-
Morandi.process(
|
110
|
-
'
|
111
|
-
'
|
112
|
-
'
|
113
|
-
'
|
114
|
-
|
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')
|
115
177
|
expect(File.exist?(out))
|
116
|
-
|
117
|
-
|
118
|
-
expect(
|
119
|
-
expect(
|
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
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
context 'with increasing quality settings' do
|
187
|
+
let(:max_quality_file_size) do
|
188
|
+
Morandi.process('sample/sample.jpg', { 'quality' => 100 }, 'sample/out-100.jpg')
|
189
|
+
File.size('sample/out-100.jpg')
|
190
|
+
end
|
191
|
+
|
192
|
+
let(:default_of_97_quality) do
|
193
|
+
Morandi.process('sample/sample.jpg', {}, 'sample/out-97.jpg')
|
194
|
+
File.size('sample/out-97.jpg')
|
195
|
+
end
|
196
|
+
|
197
|
+
let(:quality_of_40_by_options_args) do
|
198
|
+
Morandi.process('sample/sample.jpg', { 'quality' => 40 }, 'sample/out-40.jpg')
|
199
|
+
File.size('sample/out-40.jpg')
|
200
|
+
end
|
201
|
+
|
202
|
+
# Sort the output files' sizes and expect them to match to quality order
|
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])
|
120
206
|
end
|
121
207
|
end
|
122
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.0
|
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,8 @@ extra_rdoc_files: []
|
|
162
176
|
files:
|
163
177
|
- ".gitignore"
|
164
178
|
- ".rspec"
|
179
|
+
- ".ruby-version"
|
180
|
+
- CHANGELOG.md
|
165
181
|
- Gemfile
|
166
182
|
- LICENSE.txt
|
167
183
|
- README.md
|
@@ -174,6 +190,7 @@ files:
|
|
174
190
|
- lib/morandi/utils.rb
|
175
191
|
- lib/morandi/version.rb
|
176
192
|
- morandi.gemspec
|
193
|
+
- sample/100_mb_image.jpg
|
177
194
|
- sample/sample.jpg
|
178
195
|
- spec/morandi_spec.rb
|
179
196
|
- spec/spec_helper.rb
|
@@ -181,7 +198,7 @@ homepage: ''
|
|
181
198
|
licenses:
|
182
199
|
- MIT
|
183
200
|
metadata: {}
|
184
|
-
post_install_message:
|
201
|
+
post_install_message:
|
185
202
|
rdoc_options: []
|
186
203
|
require_paths:
|
187
204
|
- lib
|
@@ -196,11 +213,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
196
213
|
- !ruby/object:Gem::Version
|
197
214
|
version: '0'
|
198
215
|
requirements: []
|
199
|
-
|
200
|
-
|
201
|
-
signing_key:
|
216
|
+
rubygems_version: 3.1.2
|
217
|
+
signing_key:
|
202
218
|
specification_version: 4
|
203
219
|
summary: Simple Image Edits
|
204
220
|
test_files:
|
205
221
|
- spec/morandi_spec.rb
|
206
222
|
- spec/spec_helper.rb
|
223
|
+
...
|