morandi 0.12.0 → 0.99.03
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/CHANGELOG.md +24 -1
- data/README.md +6 -1
- data/ext/gdk_pixbuf_cairo/extconf.rb +124 -0
- data/ext/gdk_pixbuf_cairo/gdk_pixbuf_cairo.c +260 -0
- data/ext/morandi_native/extconf.rb +121 -0
- data/ext/morandi_native/filter.h +229 -0
- data/ext/morandi_native/gamma.h +48 -0
- data/ext/morandi_native/mask.h +75 -0
- data/ext/morandi_native/morandi_native.c +1126 -0
- data/ext/morandi_native/rotate.h +79 -0
- data/ext/morandi_native/tint.h +72 -0
- data/lib/gdk_pixbuf_cairo.so +0 -0
- data/lib/morandi/cairo_ext.rb +56 -0
- data/lib/morandi/crop_utils.rb +95 -0
- data/lib/morandi/image_operation.rb +205 -0
- data/lib/morandi/image_processor.rb +180 -180
- data/lib/morandi/pixbuf_ext.rb +19 -0
- data/lib/morandi/profiled_pixbuf.rb +40 -61
- data/lib/morandi/redeye.rb +35 -47
- data/lib/morandi/version.rb +3 -1
- data/lib/morandi.rb +33 -11
- data/lib/morandi_native.so +0 -0
- metadata +52 -117
- data/.gitignore +0 -18
- data/.rspec +0 -3
- data/.ruby-version +0 -1
- data/Gemfile +0 -4
- data/Rakefile +0 -1
- data/lib/morandi/image-ops.rb +0 -307
- data/lib/morandi/utils.rb +0 -136
- data/morandi.gemspec +0 -33
- data/sample/100_mb_image.jpg +0 -0
- data/sample/sample.jpg +0 -0
- data/spec/morandi_spec.rb +0 -208
- data/spec/spec_helper.rb +0 -19
data/lib/morandi.rb
CHANGED
@@ -1,20 +1,42 @@
|
|
1
|
-
|
2
|
-
require 'gtk2/base'
|
3
|
-
require 'cairo'
|
4
|
-
require 'gdk_pixbuf2'
|
5
|
-
require 'pixbufutils'
|
6
|
-
require 'redeye'
|
1
|
+
# frozen_string_literal: true
|
7
2
|
|
3
|
+
require 'morandi/version'
|
4
|
+
require 'morandi_native'
|
5
|
+
|
6
|
+
require 'morandi/cairo_ext'
|
7
|
+
require 'morandi/pixbuf_ext'
|
8
8
|
require 'morandi/image_processor'
|
9
|
-
require 'morandi/
|
10
|
-
require 'morandi/image-ops'
|
9
|
+
require 'morandi/image_operation'
|
11
10
|
require 'morandi/redeye'
|
11
|
+
require 'morandi/crop_utils'
|
12
12
|
|
13
|
+
# Morandi namespace should contain all the functionality of the gem
|
13
14
|
module Morandi
|
14
15
|
module_function
|
15
|
-
|
16
|
+
|
17
|
+
# The main entry point for the libray
|
18
|
+
#
|
19
|
+
# @param in_file [String|GdkPixbuf::Pixbuf] source image
|
20
|
+
# @param settings [Hash]
|
21
|
+
# @param out_file [String] target location for image
|
22
|
+
# @param local_options [Hash]
|
23
|
+
#
|
24
|
+
# Settings Key | Values | Description
|
25
|
+
# -------------|--------|---------------
|
26
|
+
# brighten | Integer -20..20 | Change image brightness
|
27
|
+
# gamma | Float | Gamma correct image
|
28
|
+
# contrast | Integer -20..20 | Change image contrast
|
29
|
+
# sharpen | Integer -5..5 | Sharpen / Blur (negative value)
|
30
|
+
# redeye | Array[[Integer,Integer],...] | Apply redeye correction at point
|
31
|
+
# angle | Integer 0,90,180,270 | Rotate image
|
32
|
+
# crop | Array[Integer,Integer,Integer,Integer] | Crop image
|
33
|
+
# fx | String greyscale,sepia,bluetone | Apply colour filters
|
34
|
+
# border-style | String square,retro | Set border style
|
35
|
+
# background-style | String retro,black,white | Set border colour
|
36
|
+
# quality | String '1'..'100' | Set JPG compression value, defaults to 97%
|
37
|
+
def process(file_in, options, file_out, local_options = {})
|
16
38
|
pro = ImageProcessor.new(file_in, options, local_options)
|
17
|
-
pro.
|
18
|
-
pro.write_to_jpeg(
|
39
|
+
pro.result
|
40
|
+
pro.write_to_jpeg(file_out)
|
19
41
|
end
|
20
42
|
end
|
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: morandi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.99.03
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- |+
|
@@ -11,193 +11,130 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date:
|
14
|
+
date: 2024-09-19 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
|
-
name:
|
18
|
-
requirement: !ruby/object:Gem::Requirement
|
19
|
-
requirements:
|
20
|
-
- - ">="
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: '0'
|
23
|
-
type: :runtime
|
24
|
-
prerelease: false
|
25
|
-
version_requirements: !ruby/object:Gem::Requirement
|
26
|
-
requirements:
|
27
|
-
- - ">="
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: '0'
|
30
|
-
- !ruby/object:Gem::Dependency
|
31
|
-
name: gdk_pixbuf2
|
17
|
+
name: atk
|
32
18
|
requirement: !ruby/object:Gem::Requirement
|
33
19
|
requirements:
|
34
20
|
- - "~>"
|
35
21
|
- !ruby/object:Gem::Version
|
36
|
-
version:
|
22
|
+
version: '4.0'
|
37
23
|
type: :runtime
|
38
24
|
prerelease: false
|
39
25
|
version_requirements: !ruby/object:Gem::Requirement
|
40
26
|
requirements:
|
41
27
|
- - "~>"
|
42
28
|
- !ruby/object:Gem::Version
|
43
|
-
version:
|
29
|
+
version: '4.0'
|
44
30
|
- !ruby/object:Gem::Dependency
|
45
31
|
name: cairo
|
46
32
|
requirement: !ruby/object:Gem::Requirement
|
47
33
|
requirements:
|
48
|
-
- - "
|
34
|
+
- - "~>"
|
49
35
|
- !ruby/object:Gem::Version
|
50
|
-
version: '0'
|
36
|
+
version: '1.0'
|
51
37
|
type: :runtime
|
52
38
|
prerelease: false
|
53
39
|
version_requirements: !ruby/object:Gem::Requirement
|
54
40
|
requirements:
|
55
|
-
- - "
|
41
|
+
- - "~>"
|
56
42
|
- !ruby/object:Gem::Version
|
57
|
-
version: '0'
|
43
|
+
version: '1.0'
|
58
44
|
- !ruby/object:Gem::Dependency
|
59
|
-
name:
|
45
|
+
name: colorscore
|
60
46
|
requirement: !ruby/object:Gem::Requirement
|
61
47
|
requirements:
|
62
|
-
- - "
|
48
|
+
- - "~>"
|
63
49
|
- !ruby/object:Gem::Version
|
64
|
-
version: '0'
|
50
|
+
version: '0.0'
|
65
51
|
type: :runtime
|
66
52
|
prerelease: false
|
67
53
|
version_requirements: !ruby/object:Gem::Requirement
|
68
54
|
requirements:
|
69
|
-
- - "
|
55
|
+
- - "~>"
|
70
56
|
- !ruby/object:Gem::Version
|
71
|
-
version: '0'
|
57
|
+
version: '0.0'
|
72
58
|
- !ruby/object:Gem::Dependency
|
73
|
-
name:
|
59
|
+
name: gdk_pixbuf2
|
74
60
|
requirement: !ruby/object:Gem::Requirement
|
75
61
|
requirements:
|
76
|
-
- - "
|
62
|
+
- - "~>"
|
77
63
|
- !ruby/object:Gem::Version
|
78
|
-
version: '0'
|
64
|
+
version: '4.0'
|
79
65
|
type: :runtime
|
80
66
|
prerelease: false
|
81
67
|
version_requirements: !ruby/object:Gem::Requirement
|
82
68
|
requirements:
|
83
|
-
- - "
|
69
|
+
- - "~>"
|
84
70
|
- !ruby/object:Gem::Version
|
85
|
-
version: '0'
|
71
|
+
version: '4.0'
|
86
72
|
- !ruby/object:Gem::Dependency
|
87
73
|
name: pango
|
88
74
|
requirement: !ruby/object:Gem::Requirement
|
89
75
|
requirements:
|
90
|
-
- - "
|
76
|
+
- - "~>"
|
91
77
|
- !ruby/object:Gem::Version
|
92
|
-
version: '0'
|
78
|
+
version: '4.0'
|
93
79
|
type: :runtime
|
94
80
|
prerelease: false
|
95
81
|
version_requirements: !ruby/object:Gem::Requirement
|
96
82
|
requirements:
|
97
|
-
- - "
|
83
|
+
- - "~>"
|
98
84
|
- !ruby/object:Gem::Version
|
99
|
-
version: '0'
|
85
|
+
version: '4.0'
|
100
86
|
- !ruby/object:Gem::Dependency
|
101
|
-
name:
|
87
|
+
name: rake-compiler
|
102
88
|
requirement: !ruby/object:Gem::Requirement
|
103
89
|
requirements:
|
104
|
-
- - "
|
90
|
+
- - "~>"
|
105
91
|
- !ruby/object:Gem::Version
|
106
|
-
version: '
|
92
|
+
version: '1.2'
|
107
93
|
type: :runtime
|
108
94
|
prerelease: false
|
109
95
|
version_requirements: !ruby/object:Gem::Requirement
|
110
96
|
requirements:
|
111
|
-
- - "
|
112
|
-
- !ruby/object:Gem::Version
|
113
|
-
version: '0'
|
114
|
-
- !ruby/object:Gem::Dependency
|
115
|
-
name: bundler
|
116
|
-
requirement: !ruby/object:Gem::Requirement
|
117
|
-
requirements:
|
118
|
-
- - ">="
|
119
|
-
- !ruby/object:Gem::Version
|
120
|
-
version: '0'
|
121
|
-
type: :development
|
122
|
-
prerelease: false
|
123
|
-
version_requirements: !ruby/object:Gem::Requirement
|
124
|
-
requirements:
|
125
|
-
- - ">="
|
126
|
-
- !ruby/object:Gem::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'
|
142
|
-
- !ruby/object:Gem::Dependency
|
143
|
-
name: rake
|
144
|
-
requirement: !ruby/object:Gem::Requirement
|
145
|
-
requirements:
|
146
|
-
- - ">="
|
147
|
-
- !ruby/object:Gem::Version
|
148
|
-
version: '0'
|
149
|
-
type: :development
|
150
|
-
prerelease: false
|
151
|
-
version_requirements: !ruby/object:Gem::Requirement
|
152
|
-
requirements:
|
153
|
-
- - ">="
|
154
|
-
- !ruby/object:Gem::Version
|
155
|
-
version: '0'
|
156
|
-
- !ruby/object:Gem::Dependency
|
157
|
-
name: rspec
|
158
|
-
requirement: !ruby/object:Gem::Requirement
|
159
|
-
requirements:
|
160
|
-
- - ">="
|
161
|
-
- !ruby/object:Gem::Version
|
162
|
-
version: '0'
|
163
|
-
type: :development
|
164
|
-
prerelease: false
|
165
|
-
version_requirements: !ruby/object:Gem::Requirement
|
166
|
-
requirements:
|
167
|
-
- - ">="
|
97
|
+
- - "~>"
|
168
98
|
- !ruby/object:Gem::Version
|
169
|
-
version: '
|
99
|
+
version: '1.2'
|
170
100
|
description: Apply simple edits to images
|
171
101
|
email:
|
172
102
|
- git@intersect-uk.co.uk
|
173
103
|
executables: []
|
174
|
-
extensions:
|
104
|
+
extensions:
|
105
|
+
- ext/morandi_native/extconf.rb
|
106
|
+
- ext/gdk_pixbuf_cairo/extconf.rb
|
175
107
|
extra_rdoc_files: []
|
176
108
|
files:
|
177
|
-
- ".gitignore"
|
178
|
-
- ".rspec"
|
179
|
-
- ".ruby-version"
|
180
109
|
- CHANGELOG.md
|
181
|
-
- Gemfile
|
182
110
|
- LICENSE.txt
|
183
111
|
- README.md
|
184
|
-
-
|
112
|
+
- ext/gdk_pixbuf_cairo/extconf.rb
|
113
|
+
- ext/gdk_pixbuf_cairo/gdk_pixbuf_cairo.c
|
114
|
+
- ext/morandi_native/extconf.rb
|
115
|
+
- ext/morandi_native/filter.h
|
116
|
+
- ext/morandi_native/gamma.h
|
117
|
+
- ext/morandi_native/mask.h
|
118
|
+
- ext/morandi_native/morandi_native.c
|
119
|
+
- ext/morandi_native/rotate.h
|
120
|
+
- ext/morandi_native/tint.h
|
121
|
+
- lib/gdk_pixbuf_cairo.so
|
185
122
|
- lib/morandi.rb
|
186
|
-
- lib/morandi/
|
123
|
+
- lib/morandi/cairo_ext.rb
|
124
|
+
- lib/morandi/crop_utils.rb
|
125
|
+
- lib/morandi/image_operation.rb
|
187
126
|
- lib/morandi/image_processor.rb
|
127
|
+
- lib/morandi/pixbuf_ext.rb
|
188
128
|
- lib/morandi/profiled_pixbuf.rb
|
189
129
|
- lib/morandi/redeye.rb
|
190
|
-
- lib/morandi/utils.rb
|
191
130
|
- lib/morandi/version.rb
|
192
|
-
-
|
193
|
-
|
194
|
-
- sample/sample.jpg
|
195
|
-
- spec/morandi_spec.rb
|
196
|
-
- spec/spec_helper.rb
|
197
|
-
homepage: ''
|
131
|
+
- lib/morandi_native.so
|
132
|
+
homepage: https://github.com/livelink/morandi-rb
|
198
133
|
licenses:
|
199
134
|
- MIT
|
200
|
-
metadata:
|
135
|
+
metadata:
|
136
|
+
source_code_uri: https://github.com/livelink/morandi-rb
|
137
|
+
rubygems_mfa_required: 'true'
|
201
138
|
post_install_message:
|
202
139
|
rdoc_options: []
|
203
140
|
require_paths:
|
@@ -206,7 +143,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
206
143
|
requirements:
|
207
144
|
- - ">="
|
208
145
|
- !ruby/object:Gem::Version
|
209
|
-
version: '0'
|
146
|
+
version: '2.0'
|
210
147
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
211
148
|
requirements:
|
212
149
|
- - ">="
|
@@ -217,7 +154,5 @@ rubygems_version: 3.1.2
|
|
217
154
|
signing_key:
|
218
155
|
specification_version: 4
|
219
156
|
summary: Simple Image Edits
|
220
|
-
test_files:
|
221
|
-
- spec/morandi_spec.rb
|
222
|
-
- spec/spec_helper.rb
|
157
|
+
test_files: []
|
223
158
|
...
|
data/.gitignore
DELETED
data/.rspec
DELETED
data/.ruby-version
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
2.7.1
|
data/Gemfile
DELETED
data/Rakefile
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
require "bundler/gem_tasks"
|
data/lib/morandi/image-ops.rb
DELETED
@@ -1,307 +0,0 @@
|
|
1
|
-
require 'pango'
|
2
|
-
require 'colorscore'
|
3
|
-
|
4
|
-
module Morandi
|
5
|
-
class ImageOp
|
6
|
-
class << self
|
7
|
-
def new_from_hash(hash)
|
8
|
-
op = allocate()
|
9
|
-
hash.each_pair do |key,val|
|
10
|
-
op.instance_variable_set("@#{key}", val) if op.respond_to?(key.intern)
|
11
|
-
end
|
12
|
-
op
|
13
|
-
end
|
14
|
-
end
|
15
|
-
def initialize()
|
16
|
-
end
|
17
|
-
def priority
|
18
|
-
100
|
19
|
-
end
|
20
|
-
end
|
21
|
-
class Crop < ImageOp
|
22
|
-
attr_accessor :area
|
23
|
-
def initialize(area=nil)
|
24
|
-
super()
|
25
|
-
@area = area
|
26
|
-
end
|
27
|
-
def constrain(val,min,max)
|
28
|
-
if val < min
|
29
|
-
min
|
30
|
-
elsif val > max
|
31
|
-
max
|
32
|
-
else
|
33
|
-
val
|
34
|
-
end
|
35
|
-
end
|
36
|
-
def call(image, pixbuf)
|
37
|
-
if @area and (not @area.width.zero?) and (not @area.height.zero?)
|
38
|
-
# NB: Cheap - fast & shares memory
|
39
|
-
GdkPixbuf::Pixbuf.new(pixbuf, @area.x, @area.y,
|
40
|
-
@area.width, @area.height)
|
41
|
-
else
|
42
|
-
pixbuf
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
class Rotate < ImageOp
|
47
|
-
attr_accessor :angle
|
48
|
-
def initialize(angle=0)
|
49
|
-
super()
|
50
|
-
@angle = angle
|
51
|
-
end
|
52
|
-
def call(image, pixbuf)
|
53
|
-
if @angle.zero?
|
54
|
-
pixbuf
|
55
|
-
else
|
56
|
-
case @angle
|
57
|
-
when 0, 90, 180, 270
|
58
|
-
PixbufUtils::rotate(pixbuf, @angle)
|
59
|
-
else
|
60
|
-
raise "Not a valid angle"
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
class Straighten < ImageOp
|
66
|
-
attr_accessor :angle
|
67
|
-
def initialize(angle=0)
|
68
|
-
super()
|
69
|
-
@angle = angle
|
70
|
-
end
|
71
|
-
def call(image, pixbuf)
|
72
|
-
if @angle.zero?
|
73
|
-
pixbuf
|
74
|
-
else
|
75
|
-
surface = Cairo::ImageSurface.new(:rgb24, pixbuf.width, pixbuf.height)
|
76
|
-
|
77
|
-
rotationValueRad = @angle * (Math::PI/180)
|
78
|
-
|
79
|
-
ratio = pixbuf.width.to_f/pixbuf.height
|
80
|
-
rh = (pixbuf.height) / ((ratio * Math.sin(rotationValueRad.abs)) + Math.cos(rotationValueRad.abs))
|
81
|
-
scale = pixbuf.height / rh.to_f.abs
|
82
|
-
|
83
|
-
a_ratio = pixbuf.height.to_f/pixbuf.width
|
84
|
-
a_rh = (pixbuf.width) / ((a_ratio * Math.sin(rotationValueRad.abs)) + Math.cos(rotationValueRad.abs))
|
85
|
-
a_scale = pixbuf.width / a_rh.to_f.abs
|
86
|
-
|
87
|
-
scale = a_scale if a_scale > scale
|
88
|
-
|
89
|
-
cr = Cairo::Context.new(surface)
|
90
|
-
#p [@angle, rotationValueRad, rh, scale, pixbuf.height]
|
91
|
-
|
92
|
-
cr.translate(pixbuf.width / 2.0, pixbuf.height / 2.0)
|
93
|
-
cr.rotate(rotationValueRad)
|
94
|
-
cr.scale(scale, scale)
|
95
|
-
cr.translate(pixbuf.width / -2.0, pixbuf.height / - 2.0)
|
96
|
-
cr.set_source_pixbuf(pixbuf)
|
97
|
-
|
98
|
-
cr.rectangle(0, 0, pixbuf.width, pixbuf.height)
|
99
|
-
cr.paint(1.0)
|
100
|
-
final_pb = surface.to_pixbuf
|
101
|
-
cr.destroy
|
102
|
-
surface.destroy
|
103
|
-
return final_pb
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
class ImageCaption < ImageOp
|
109
|
-
attr_accessor :text, :font, :position
|
110
|
-
def initialize()
|
111
|
-
super()
|
112
|
-
end
|
113
|
-
|
114
|
-
def font
|
115
|
-
@font || "Open Sans Condensed Light #{ ([@pixbuf.width,@pixbuf.height].max/80.0).to_i }"
|
116
|
-
end
|
117
|
-
|
118
|
-
def position
|
119
|
-
@position ||
|
120
|
-
(@pixbuf ? ([ [@pixbuf.width,@pixbuf.height].max/20 ] * 2) : [100, 100])
|
121
|
-
end
|
122
|
-
|
123
|
-
def call(image, pixbuf)
|
124
|
-
@pixbuf = pixbuf
|
125
|
-
surface = Cairo::ImageSurface.new(:rgb24, pixbuf.width, pixbuf.height)
|
126
|
-
cr = Cairo::Context.new(surface)
|
127
|
-
|
128
|
-
cr.save do
|
129
|
-
cr.set_source_pixbuf(pixbuf)
|
130
|
-
#cr.rectangle(0, 0, pixbuf.width, pixbuf.height)
|
131
|
-
cr.paint(1.0)
|
132
|
-
cr.translate(*self.position)
|
133
|
-
|
134
|
-
layout = cr.create_pango_layout
|
135
|
-
layout.set_text(self.text)
|
136
|
-
fd = Pango::FontDescription.new(self.font)
|
137
|
-
layout.font_description = fd
|
138
|
-
layout.set_width((pixbuf.width - self.position[0] - 100)*Pango::SCALE)
|
139
|
-
layout.context_changed
|
140
|
-
ink, _ = layout.pixel_extents
|
141
|
-
cr.set_source_rgba(0, 0, 0, 0.3)
|
142
|
-
cr.rectangle(-25, -25, ink.width + 50, ink.height + 50)
|
143
|
-
cr.fill
|
144
|
-
cr.set_source_rgb(1, 1, 1)
|
145
|
-
cr.show_pango_layout(layout)
|
146
|
-
end
|
147
|
-
|
148
|
-
|
149
|
-
final_pb = surface.to_pixbuf
|
150
|
-
cr.destroy
|
151
|
-
surface.destroy
|
152
|
-
return final_pb
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
class ImageBorder < ImageOp
|
157
|
-
attr_accessor :style, :colour, :crop, :size, :print_size, :shrink, :border_size
|
158
|
-
def initialize(style='none', colour='white')
|
159
|
-
super()
|
160
|
-
@style = style
|
161
|
-
@colour = colour
|
162
|
-
end
|
163
|
-
|
164
|
-
def call(image, pixbuf)
|
165
|
-
return pixbuf unless %w[square retro].include? @style
|
166
|
-
surface = Cairo::ImageSurface.new(:rgb24, pixbuf.width, pixbuf.height)
|
167
|
-
cr = Cairo::Context.new(surface)
|
168
|
-
|
169
|
-
img_width = pixbuf.width
|
170
|
-
img_height = pixbuf.height
|
171
|
-
|
172
|
-
cr.save do
|
173
|
-
if @crop
|
174
|
-
if @crop[0] < 0 || @crop[1] < 0
|
175
|
-
img_width = size[0]
|
176
|
-
img_height = size[1]
|
177
|
-
cr.translate( - @crop[0], - @crop[1])
|
178
|
-
end
|
179
|
-
end
|
180
|
-
|
181
|
-
cr.save do
|
182
|
-
cr.set_operator :source
|
183
|
-
cr.set_source_rgb 1, 1, 1
|
184
|
-
cr.paint
|
185
|
-
|
186
|
-
cr.rectangle(0, 0, img_width, img_height)
|
187
|
-
case colour
|
188
|
-
when 'dominant'
|
189
|
-
pixbuf.scale_max(400).save(fn="/tmp/hist-#{$$}.#{Time.now.to_i}", 'jpeg')
|
190
|
-
hgram = Colorscore::Histogram.new(fn)
|
191
|
-
File.unlink(fn) rescue nil
|
192
|
-
col = hgram.scores.first[1]
|
193
|
-
cr.set_source_rgb col.red/256.0, col.green/256.0, col.blue/256.0
|
194
|
-
when 'retro'
|
195
|
-
cr.set_source_rgb 1, 1, 0.8
|
196
|
-
when 'black'
|
197
|
-
cr.set_source_rgb 0, 0, 0
|
198
|
-
else
|
199
|
-
cr.set_source_rgb 1, 1, 1
|
200
|
-
end
|
201
|
-
cr.fill
|
202
|
-
end
|
203
|
-
end
|
204
|
-
|
205
|
-
border_scale = [img_width,img_height].max.to_f / print_size.max.to_i
|
206
|
-
size = @border_size
|
207
|
-
size *= border_scale
|
208
|
-
x, y = size, size
|
209
|
-
|
210
|
-
# This biggest impact will be on the smallest side, so to avoid white
|
211
|
-
# edges between photo and border scale by the longest changed side.
|
212
|
-
longest_side = [pixbuf.width, pixbuf.height].max.to_f
|
213
|
-
|
214
|
-
# Should be less than 1
|
215
|
-
pb_scale = (longest_side - (size * 2)) / longest_side
|
216
|
-
|
217
|
-
if @crop
|
218
|
-
if @crop[0] < 0 || @crop[1] < 0
|
219
|
-
x -= @crop[0]
|
220
|
-
y -= @crop[1]
|
221
|
-
end
|
222
|
-
end
|
223
|
-
|
224
|
-
case style
|
225
|
-
when 'retro'
|
226
|
-
# WARNING: CairoUtils class is not available in this gem!
|
227
|
-
CairoUtils.rounded_rectangle(cr, x, y,
|
228
|
-
img_width + x - (size*2), img_height+y-(size*2), size)
|
229
|
-
when 'square'
|
230
|
-
cr.rectangle(x, y, img_width - (size*2), img_height - (size*2))
|
231
|
-
end
|
232
|
-
cr.clip()
|
233
|
-
|
234
|
-
if @shrink
|
235
|
-
cr.translate(size, size)
|
236
|
-
cr.scale(pb_scale, pb_scale)
|
237
|
-
end
|
238
|
-
cr.set_source_pixbuf(pixbuf)
|
239
|
-
cr.rectangle(0, 0, pixbuf.width, pixbuf.height)
|
240
|
-
|
241
|
-
cr.paint(1.0)
|
242
|
-
final_pb = surface.to_pixbuf
|
243
|
-
cr.destroy
|
244
|
-
surface.destroy
|
245
|
-
return final_pb
|
246
|
-
end
|
247
|
-
end
|
248
|
-
|
249
|
-
class Gamma < ImageOp
|
250
|
-
attr_reader :gamma
|
251
|
-
def initialize(gamma=1.0)
|
252
|
-
super()
|
253
|
-
@gamma = gamma
|
254
|
-
end
|
255
|
-
def call(image, pixbuf)
|
256
|
-
if @gamma == 1.0
|
257
|
-
pixbuf
|
258
|
-
else
|
259
|
-
PixbufUtils.gamma(pixbuf, @gamma)
|
260
|
-
end
|
261
|
-
end
|
262
|
-
def priority
|
263
|
-
90
|
264
|
-
end
|
265
|
-
end
|
266
|
-
|
267
|
-
class Colourify < ImageOp
|
268
|
-
attr_reader :op
|
269
|
-
def initialize(op, alpha=255)
|
270
|
-
super()
|
271
|
-
@op = op
|
272
|
-
@alpha = alpha
|
273
|
-
end
|
274
|
-
|
275
|
-
def alpha
|
276
|
-
@alpha || 255
|
277
|
-
end
|
278
|
-
|
279
|
-
def sepia(pixbuf)
|
280
|
-
PixbufUtils.tint(pixbuf, 25, 5, -25, alpha)
|
281
|
-
end
|
282
|
-
|
283
|
-
def bluetone(pixbuf)
|
284
|
-
PixbufUtils.tint(pixbuf, -10, 5, 25, alpha)
|
285
|
-
end
|
286
|
-
|
287
|
-
def null(pixbuf)
|
288
|
-
pixbuf
|
289
|
-
end
|
290
|
-
alias :full :null # WebKiosk
|
291
|
-
alias :colour :null # WebKiosk
|
292
|
-
|
293
|
-
def greyscale(pixbuf)
|
294
|
-
PixbufUtils.tint(pixbuf, 0, 0, 0, alpha)
|
295
|
-
end
|
296
|
-
alias :bw :greyscale # WebKiosk
|
297
|
-
|
298
|
-
def call(image, pixbuf)
|
299
|
-
if @op and respond_to?(@op)
|
300
|
-
__send__(@op, pixbuf)
|
301
|
-
else
|
302
|
-
pixbuf # Default is nothing
|
303
|
-
end
|
304
|
-
end
|
305
|
-
end
|
306
|
-
|
307
|
-
end
|