imgry 0.1.3 → 0.1.4
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.
- data/lib/imgry/geometry.rb +24 -4
- data/lib/imgry/processor/image_voodoo.rb +8 -4
- data/lib/imgry/processor/img_scalr.rb +7 -116
- data/lib/imgry/processor/java_adapter.rb +31 -11
- data/lib/imgry/processor/mini_magick.rb +22 -16
- data/lib/imgry/processor.rb +14 -8
- data/lib/imgry/version.rb +1 -1
- data/lib/imgry.rb +4 -4
- data/spec/imgry/geometry_spec.rb +67 -0
- data/spec/imgry/processor/image_voodoo_spec.rb +41 -1
- data/spec/imgry/processor/img_scalr_spec.rb +41 -1
- data/spec/imgry/processor/mini_magick_spec.rb +28 -2
- data/spec/imgry_spec.rb +19 -1
- data/spec/support/335is_3.jpg +0 -0
- data/spec/support/cmyk.jpg +0 -0
- data/spec/support/mexico-cmyk.jpg +0 -0
- data/spec/support/transparent_background.png +0 -0
- data/spec/support/transparent_background_saved.png +0 -0
- metadata +33 -25
- data/spec/imgry/imgry_spec.rb +0 -36
data/lib/imgry/geometry.rb
CHANGED
@@ -4,13 +4,12 @@ module Imgry
|
|
4
4
|
|
5
5
|
def scale(orig_width, orig_height, geometry)
|
6
6
|
# TODO: basic verification of geometry syntax
|
7
|
-
|
8
|
-
op = geometry[-1] # Expecting !, >, <, or nothing
|
9
7
|
new_width, new_height = nil, nil
|
10
|
-
ask_width, ask_height = geometry
|
8
|
+
ask_width, ask_height, _, _, op = from_s(geometry)
|
9
|
+
|
11
10
|
ask_height ||= 0
|
12
11
|
aspect_ratio = orig_width.to_f / orig_height.to_f
|
13
|
-
|
12
|
+
|
14
13
|
scale = Proc.new do
|
15
14
|
if ask_width == 0 || ask_width < ask_height
|
16
15
|
new_width, new_height = scale_by_height(ask_height, aspect_ratio)
|
@@ -41,5 +40,26 @@ module Imgry
|
|
41
40
|
[(new_height * aspect_ratio).to_i, new_height.to_i]
|
42
41
|
end
|
43
42
|
|
43
|
+
# borrowed from RMagick
|
44
|
+
W = /(\d+\.\d+%?)|(\d*%?)/
|
45
|
+
H = W
|
46
|
+
X = /(?:([-+]\d+))?/
|
47
|
+
Y = X
|
48
|
+
REGEXP = /\A#{W}x?#{H}#{X}#{Y}([!<>@\^]?)\Z/
|
49
|
+
|
50
|
+
def from_s(str)
|
51
|
+
m = REGEXP.match(str)
|
52
|
+
if m
|
53
|
+
width = (m[1] || m[2]).to_f
|
54
|
+
height = (m[3] || m[4]).to_f
|
55
|
+
x = m[5].to_i
|
56
|
+
y = m[6].to_i
|
57
|
+
flag = m[7]
|
58
|
+
else
|
59
|
+
raise ArgumentError, "invalid geometry format"
|
60
|
+
end
|
61
|
+
[width, height, x, y, flag]
|
62
|
+
end
|
63
|
+
|
44
64
|
end
|
45
65
|
end
|
@@ -4,7 +4,9 @@ module Imgry
|
|
4
4
|
class ImageVoodoo < JavaAdapter
|
5
5
|
def load_image!
|
6
6
|
begin
|
7
|
-
|
7
|
+
input_stream = ImageIO.create_image_input_stream(ByteArrayInputStream.new(@img_blob))
|
8
|
+
detect_image_format!(input_stream)
|
9
|
+
@img = ::ImageVoodoo.new(ImageIO.read(input_stream))
|
8
10
|
rescue => ex
|
9
11
|
raise InvalidImageError, ex.message
|
10
12
|
end
|
@@ -15,12 +17,14 @@ module Imgry
|
|
15
17
|
end
|
16
18
|
|
17
19
|
def resize!(geometry)
|
18
|
-
return if geometry.nil?
|
20
|
+
return if geometry.nil?
|
19
21
|
@img = @img.resize(*Geometry.scale(width, height, geometry))
|
20
22
|
end
|
21
23
|
|
22
|
-
def crop!
|
23
|
-
|
24
|
+
def crop!(geometry)
|
25
|
+
width, height, offset_x, offset_y, flag = crop_geometry(geometry)
|
26
|
+
|
27
|
+
@img = @img.with_crop(offset_x, offset_y, offset_x + width, offset_y + height)
|
24
28
|
end
|
25
29
|
|
26
30
|
end
|
@@ -7,7 +7,9 @@ module Imgry
|
|
7
7
|
|
8
8
|
def load_image!
|
9
9
|
begin
|
10
|
-
|
10
|
+
input_stream = ImageIO.create_image_input_stream(ByteArrayInputStream.new(@img_blob))
|
11
|
+
detect_image_format!(input_stream)
|
12
|
+
@img = ImageIO.read(input_stream)
|
11
13
|
rescue => ex
|
12
14
|
raise InvalidImageError, ex.message
|
13
15
|
end
|
@@ -28,124 +30,13 @@ module Imgry
|
|
28
30
|
Scalr::OP_ANTIALIAS)
|
29
31
|
end
|
30
32
|
|
31
|
-
def crop!
|
32
|
-
|
33
|
+
def crop!(geometry)
|
34
|
+
width, height, offset_x, offset_y, flag = crop_geometry(geometry)
|
35
|
+
|
36
|
+
@img = Scalr.crop(@img, offset_x, offset_y, width, height)
|
33
37
|
end
|
34
38
|
|
35
39
|
end
|
36
40
|
|
37
41
|
end
|
38
42
|
end
|
39
|
-
|
40
|
-
__END__
|
41
|
-
class ImgScalrVoodoo
|
42
|
-
include Java
|
43
|
-
|
44
|
-
require 'java/imgscalr-lib-4.2.jar'
|
45
|
-
|
46
|
-
java_import javax.imageio.ImageIO
|
47
|
-
java_import org.imgscalr.Scalr
|
48
|
-
java_import java.awt.image.BufferedImage
|
49
|
-
|
50
|
-
JFile = java.io.File
|
51
|
-
|
52
|
-
def initialize(src)
|
53
|
-
@src = src
|
54
|
-
end
|
55
|
-
|
56
|
-
def self.with_image(path)
|
57
|
-
raise ArgumentError, "file does not exist" unless File.file?(path)
|
58
|
-
image = guard do
|
59
|
-
buffered_image = ImageIO.read(JFile.new(path))
|
60
|
-
buffered_image ? ImgScalrVoodoo.new(buffered_image) : nil
|
61
|
-
end
|
62
|
-
|
63
|
-
image && block_given? ? yield(image) : image
|
64
|
-
end
|
65
|
-
|
66
|
-
|
67
|
-
def self.with_bytes(bytes)
|
68
|
-
bytes = bytes.to_java_bytes if String === bytes
|
69
|
-
image = guard do
|
70
|
-
ImgScalrVoodoo.new(ImageIO.read(ByteArrayInputStream.new(bytes)))
|
71
|
-
end
|
72
|
-
|
73
|
-
block_given? ? yield(image) : image
|
74
|
-
end
|
75
|
-
|
76
|
-
def img_scalr_resize(width, height, options={})
|
77
|
-
method = options[:method]? options[:method] : Scalr::Method::QUALITY
|
78
|
-
mode = options[:mode]? options[:mode] : Scalr::Mode::FIT_EXACT
|
79
|
-
ops = options[:ops]? options[:ops] : Scalr::OP_ANTIALIAS
|
80
|
-
|
81
|
-
target = guard { Scalr.resize(@src, method, mode, width, height, ops) }
|
82
|
-
|
83
|
-
image = ImgScalrVoodoo.new(target)
|
84
|
-
|
85
|
-
block_given? ? yield(image) : image
|
86
|
-
rescue NativeException => ne
|
87
|
-
raise ArgumentError, ne.message
|
88
|
-
end
|
89
|
-
|
90
|
-
def resize(width, height)
|
91
|
-
image = img_scalr_resize(width, height)
|
92
|
-
block_given? ? yield(image) : image
|
93
|
-
end
|
94
|
-
|
95
|
-
def cropped_thumbnail(size)
|
96
|
-
l, t, r, b, half = 0, 0, width, height, (width - height).abs / 2
|
97
|
-
l, r = half, half + height if width > height
|
98
|
-
t, b = half, half + width if height > width
|
99
|
-
|
100
|
-
target = with_crop(l, t, r, b).thumbnail(size)
|
101
|
-
block_given? ? yield(target) : target
|
102
|
-
end
|
103
|
-
|
104
|
-
def save(file)
|
105
|
-
format = File.extname(file)
|
106
|
-
return false if format == ""
|
107
|
-
format = format[1..-1].downcase
|
108
|
-
guard { ImageIO.write(@src, format, JFile.new(file)) }
|
109
|
-
true
|
110
|
-
end
|
111
|
-
|
112
|
-
def scale(ratio)
|
113
|
-
new_width, new_height = (width * ratio).to_i, (height * ratio).to_i
|
114
|
-
target = resize(new_width, new_height)
|
115
|
-
block_given? ? yield(target) : target
|
116
|
-
end
|
117
|
-
|
118
|
-
def thumbnail(size)
|
119
|
-
target = scale(size.to_f / (width > height ? width : height))
|
120
|
-
block_given? ? yield(target) : target
|
121
|
-
end
|
122
|
-
|
123
|
-
def with_crop(left, top, right, bottom)
|
124
|
-
image = guard { ImgScalrVoodoo.new(Scalr.crop(@src, left, top, right-left, bottom-top)) }
|
125
|
-
block_given? ? yield(image) : image
|
126
|
-
end
|
127
|
-
|
128
|
-
def self.guard(&block)
|
129
|
-
begin
|
130
|
-
return block.call
|
131
|
-
rescue NoMethodError => e
|
132
|
-
"Unimplemented Feature: #{e}"
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
def guard(&block)
|
137
|
-
ImgScalrVoodoo.guard(&block)
|
138
|
-
end
|
139
|
-
|
140
|
-
def height
|
141
|
-
@src.height
|
142
|
-
end
|
143
|
-
|
144
|
-
def width
|
145
|
-
@src.width
|
146
|
-
end
|
147
|
-
|
148
|
-
def to_java
|
149
|
-
@src
|
150
|
-
end
|
151
|
-
end
|
@@ -13,27 +13,31 @@ module Imgry
|
|
13
13
|
# GPU performance is improved
|
14
14
|
java.lang.System.setProperty('sun.java2d.opengl', 'true')
|
15
15
|
|
16
|
-
def self.with_bytes(img_blob
|
16
|
+
def self.with_bytes(img_blob)
|
17
17
|
bytes = img_blob.to_java_bytes if img_blob.is_a?(String)
|
18
|
-
new(
|
18
|
+
new(bytes)
|
19
19
|
end
|
20
20
|
|
21
|
-
def self.from_file(path
|
21
|
+
def self.from_file(path)
|
22
22
|
if !File.readable?(path)
|
23
23
|
raise FileUnreadableError, path.to_s
|
24
24
|
end
|
25
25
|
|
26
|
-
# Use the format based on the file's extension
|
27
|
-
ext = File.extname(path)
|
28
|
-
format = !ext.nil? ? ext[1..-1].downcase : nil
|
29
|
-
|
30
26
|
img_blob = IO.read(path.to_s)
|
31
|
-
with_bytes(img_blob
|
27
|
+
with_bytes(img_blob)
|
32
28
|
|
33
29
|
# TODO: read the file using Java file io instead..?
|
34
30
|
# input_stream = java.io.FileInputStream.new(java.io.File.new(path.to_s))
|
35
31
|
end
|
36
32
|
|
33
|
+
def detect_image_format!(image_input_stream)
|
34
|
+
@format = nil # reset..
|
35
|
+
if (reader = ImageIO.get_image_readers(image_input_stream).first)
|
36
|
+
@format = reader.format_name.downcase
|
37
|
+
@format = 'jpg' if @format == 'jpeg' # prefer this way..
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
37
41
|
def self.supported_formats
|
38
42
|
@supported_formats ||= begin
|
39
43
|
# NOTE: assuming read and write formats are the same..
|
@@ -42,6 +46,10 @@ module Imgry
|
|
42
46
|
end
|
43
47
|
end
|
44
48
|
|
49
|
+
def format
|
50
|
+
@format
|
51
|
+
end
|
52
|
+
|
45
53
|
def width
|
46
54
|
@img.width
|
47
55
|
end
|
@@ -55,8 +63,21 @@ module Imgry
|
|
55
63
|
@img_blob = nil
|
56
64
|
end
|
57
65
|
|
66
|
+
def crop_geometry(geometry)
|
67
|
+
# no gravity support yet, so all offsets should be > 0
|
68
|
+
width, height, offset_x, offset_y, flag = Geometry.from_s(geometry)
|
69
|
+
|
70
|
+
offset_x = 0 if offset_x > self.width || offset_x < 0
|
71
|
+
offset_y = 0 if offset_y > self.height || offset_y < 0
|
72
|
+
|
73
|
+
width = self.width - offset_x if width + offset_x > self.width
|
74
|
+
height = self.height - offset_y if height + offset_y > self.height
|
75
|
+
|
76
|
+
[width, height, offset_x, offset_y, flag]
|
77
|
+
end
|
78
|
+
|
58
79
|
def to_blob(format=nil)
|
59
|
-
format ||= @format
|
80
|
+
format ||= @format
|
60
81
|
|
61
82
|
if !self.class.supported_formats.include?(format.downcase)
|
62
83
|
raise UnsupportedFormatError, format
|
@@ -73,8 +94,7 @@ module Imgry
|
|
73
94
|
end
|
74
95
|
|
75
96
|
ext = File.extname(path)
|
76
|
-
format = !ext.nil? ? ext[1..-1].downcase :
|
77
|
-
format ||= DEFAULT_OUTPUT_FORMAT
|
97
|
+
format = !ext.nil? ? ext[1..-1].downcase : @format
|
78
98
|
|
79
99
|
if !self.class.supported_formats.include?(format)
|
80
100
|
raise UnsupportedFormatError, format
|
@@ -3,27 +3,21 @@ module Imgry
|
|
3
3
|
|
4
4
|
class MiniMagick < Adapter
|
5
5
|
|
6
|
-
def self.with_bytes(img_blob
|
7
|
-
new(img_blob
|
6
|
+
def self.with_bytes(img_blob)
|
7
|
+
new(img_blob)
|
8
8
|
end
|
9
9
|
|
10
|
-
def self.from_file(path
|
10
|
+
def self.from_file(path)
|
11
11
|
if !File.readable?(path)
|
12
12
|
raise FileUnreadableError, path.to_s
|
13
13
|
end
|
14
14
|
|
15
|
-
new(IO.read(path)
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.supported_formats
|
19
|
-
# Hardcoded list of supported formats for validity checking..
|
20
|
-
# Image/GraphicsMagick have a much more extensive list.
|
21
|
-
# Submit an issue if this is a problem.
|
22
|
-
['bmp', 'jpg', 'wbmp', 'jpeg', 'gif', 'png', 'png32', 'png24', 'png8', 'tiff']
|
15
|
+
new(IO.read(path))
|
23
16
|
end
|
24
17
|
|
25
18
|
def load_image!
|
26
19
|
begin
|
20
|
+
@format = nil
|
27
21
|
@img = ::MiniMagick::Image.read(@img_blob)
|
28
22
|
rescue ::MiniMagick::Invalid => ex
|
29
23
|
raise InvalidImageError, ex.message
|
@@ -36,6 +30,12 @@ module Imgry
|
|
36
30
|
nil
|
37
31
|
end
|
38
32
|
|
33
|
+
def crop!(geometry)
|
34
|
+
return if geometry.nil?
|
35
|
+
@img.crop(geometry)
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
|
39
39
|
def width
|
40
40
|
@img['width']
|
41
41
|
end
|
@@ -45,10 +45,18 @@ module Imgry
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def format
|
48
|
-
@
|
48
|
+
@format ||= begin
|
49
|
+
format = @img['format']
|
50
|
+
if !format.nil?
|
51
|
+
# Normalize..
|
52
|
+
format.downcase!
|
53
|
+
format == 'jpeg' ? 'jpg' : format
|
54
|
+
end
|
55
|
+
end
|
49
56
|
end
|
50
57
|
|
51
|
-
def to_blob
|
58
|
+
def to_blob(format=nil)
|
59
|
+
# TODO: support other output format
|
52
60
|
@img.to_blob
|
53
61
|
end
|
54
62
|
|
@@ -56,9 +64,7 @@ module Imgry
|
|
56
64
|
if !File.writable?(File.dirname(path))
|
57
65
|
raise FileUnwritableError, path.to_s
|
58
66
|
end
|
59
|
-
|
60
|
-
raise UnsupportedFormatError, format
|
61
|
-
end
|
67
|
+
# TODO: error checking on write
|
62
68
|
@img.write(path.to_s)
|
63
69
|
end
|
64
70
|
|
data/lib/imgry/processor.rb
CHANGED
@@ -2,26 +2,34 @@ module Imgry
|
|
2
2
|
module Processor
|
3
3
|
|
4
4
|
class Adapter
|
5
|
-
DEFAULT_OUTPUT_FORMAT = 'jpg'
|
6
|
-
|
7
5
|
def self.load_lib!
|
8
6
|
end
|
9
7
|
|
10
|
-
def self.with_bytes(img_bytes
|
8
|
+
def self.with_bytes(img_bytes)
|
11
9
|
# Abstract
|
12
10
|
end
|
13
11
|
|
14
|
-
def self.from_file(path
|
12
|
+
def self.from_file(path)
|
15
13
|
# Abstract
|
16
14
|
end
|
17
15
|
|
18
|
-
|
16
|
+
attr_accessor :img, :img_blob, :format
|
17
|
+
|
18
|
+
def initialize(img_blob)
|
19
19
|
@img_blob = img_blob
|
20
|
-
@format =
|
20
|
+
@format = nil
|
21
21
|
@img = nil
|
22
22
|
load_image!
|
23
23
|
end
|
24
24
|
|
25
|
+
def inspect
|
26
|
+
if @format
|
27
|
+
"#<#{self.class} format: #{@format}>"
|
28
|
+
else
|
29
|
+
"#<#{self.class}>"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
25
33
|
def load_image!
|
26
34
|
# Abstract
|
27
35
|
end
|
@@ -30,8 +38,6 @@ module Imgry
|
|
30
38
|
width.to_f / height.to_f
|
31
39
|
end
|
32
40
|
|
33
|
-
# TODO .. add abstract methods.. at least comments..
|
34
|
-
|
35
41
|
end
|
36
42
|
|
37
43
|
end
|
data/lib/imgry/version.rb
CHANGED
data/lib/imgry.rb
CHANGED
@@ -3,12 +3,12 @@ module Imgry
|
|
3
3
|
|
4
4
|
attr_accessor :processor
|
5
5
|
|
6
|
-
def with_bytes(img_blob
|
7
|
-
processor_klass.with_bytes(img_blob
|
6
|
+
def with_bytes(img_blob)
|
7
|
+
processor_klass.with_bytes(img_blob)
|
8
8
|
end
|
9
9
|
|
10
|
-
def from_file(
|
11
|
-
processor_klass.from_file(
|
10
|
+
def from_file(path)
|
11
|
+
processor_klass.from_file(path)
|
12
12
|
end
|
13
13
|
|
14
14
|
def processor_klass
|
data/spec/imgry/geometry_spec.rb
CHANGED
@@ -33,4 +33,71 @@ describe Imgry::Geometry do
|
|
33
33
|
size.should == [600, 800]
|
34
34
|
end
|
35
35
|
|
36
|
+
context "#from_s" do
|
37
|
+
it 'handles geometry format: WxH+X+Y>' do
|
38
|
+
geometry_str = "200x300+10+20!"
|
39
|
+
width, height, offset_x, offset_y, flag = Imgry::Geometry.from_s(geometry_str)
|
40
|
+
|
41
|
+
width.should == 200
|
42
|
+
height.should == 300
|
43
|
+
offset_x.should == 10
|
44
|
+
offset_y.should == 20
|
45
|
+
flag.should == '!'
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'handles geometry format: Wx>' do
|
49
|
+
geometry_str = "200x"
|
50
|
+
width, height, offset_x, offset_y, flag = Imgry::Geometry.from_s(geometry_str)
|
51
|
+
|
52
|
+
width.should == 200
|
53
|
+
height.should == 0
|
54
|
+
offset_x.should == 0
|
55
|
+
offset_y.should == 0
|
56
|
+
flag.should == ''
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'handles geometry format: WxH>' do
|
60
|
+
geometry_str = "200x300"
|
61
|
+
width, height, offset_x, offset_y, flag = Imgry::Geometry.from_s(geometry_str)
|
62
|
+
|
63
|
+
width.should == 200
|
64
|
+
height.should == 300
|
65
|
+
offset_x.should == 0
|
66
|
+
offset_y.should == 0
|
67
|
+
flag.should == ''
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'handles geometry format: WxH>' do
|
71
|
+
geometry_str = "200x300>"
|
72
|
+
width, height, offset_x, offset_y, flag = Imgry::Geometry.from_s(geometry_str)
|
73
|
+
|
74
|
+
width.should == 200
|
75
|
+
height.should == 300
|
76
|
+
offset_x.should == 0
|
77
|
+
offset_y.should == 0
|
78
|
+
flag.should == '>'
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'handles geometry format: WxH+X' do
|
82
|
+
geometry_str = "200x300+10"
|
83
|
+
width, height, offset_x, offset_y, flag = Imgry::Geometry.from_s(geometry_str)
|
84
|
+
|
85
|
+
width.should == 200
|
86
|
+
height.should == 300
|
87
|
+
offset_x.should == 10
|
88
|
+
offset_y.should == 0
|
89
|
+
flag.should == ''
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'handles geometry format: WxH+X>' do
|
93
|
+
geometry_str = "200x300+10>"
|
94
|
+
width, height, offset_x, offset_y, flag = Imgry::Geometry.from_s(geometry_str)
|
95
|
+
|
96
|
+
width.should == 200
|
97
|
+
height.should == 300
|
98
|
+
offset_x.should == 10
|
99
|
+
offset_y.should == 0
|
100
|
+
flag.should == '>'
|
101
|
+
end
|
102
|
+
end
|
36
103
|
end
|
@@ -4,8 +4,9 @@ if RUBY_ENGINE == 'jruby'
|
|
4
4
|
describe Imgry::Processor::ImageVoodoo do
|
5
5
|
|
6
6
|
let (:img_data) { IO.read(SPEC_ROOT.join('support/335is.jpg')) }
|
7
|
+
let (:transparent_img_data) { IO.read(SPEC_ROOT.join('support/transparent_background.png')) }
|
7
8
|
|
8
|
-
context "a pretty picture" do
|
9
|
+
context "a pretty picture" do
|
9
10
|
|
10
11
|
it "basic loading and resizing of an image" do
|
11
12
|
img = Imgry::Processor::ImageVoodoo.with_bytes(img_data)
|
@@ -22,7 +23,46 @@ if RUBY_ENGINE == 'jruby'
|
|
22
23
|
new_img_blob.length.should == 32159
|
23
24
|
end
|
24
25
|
|
26
|
+
it "crops an image" do
|
27
|
+
img = Imgry::Processor::ImageVoodoo.with_bytes(img_data)
|
28
|
+
|
29
|
+
img.width.should == 1024
|
30
|
+
img.height.should == 764
|
31
|
+
|
32
|
+
img.crop!("300x200+100+300")
|
33
|
+
img.width.should == 300
|
34
|
+
img.height.should == 200
|
35
|
+
end
|
36
|
+
|
37
|
+
it "handles offsets properly when cropping an image" do
|
38
|
+
img = Imgry::Processor::ImageVoodoo.with_bytes(img_data)
|
39
|
+
|
40
|
+
img.crop!("300x200+800+600")
|
41
|
+
img.width.should == 224
|
42
|
+
img.height.should == 164
|
43
|
+
end
|
44
|
+
|
25
45
|
end
|
26
46
|
|
47
|
+
context "image format" do
|
48
|
+
|
49
|
+
it "corrects passed in format" do
|
50
|
+
img = Imgry::Processor::ImageVoodoo.with_bytes(img_data)
|
51
|
+
img.format.should == 'jpg'
|
52
|
+
end
|
53
|
+
|
54
|
+
it "knows how to detect jpg files" do
|
55
|
+
img = Imgry::Processor::ImageVoodoo.with_bytes(img_data)
|
56
|
+
img.format.should == 'jpg'
|
57
|
+
end
|
58
|
+
|
59
|
+
it "knows how to detect png files" do
|
60
|
+
img = Imgry::Processor::ImageVoodoo.with_bytes(transparent_img_data)
|
61
|
+
img.format.should == 'png'
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
|
27
67
|
end
|
28
68
|
end
|
@@ -4,8 +4,9 @@ if RUBY_ENGINE == 'jruby'
|
|
4
4
|
describe Imgry::Processor::ImgScalr do
|
5
5
|
|
6
6
|
let (:img_data) { IO.read(SPEC_ROOT.join('support/335is.jpg')) }
|
7
|
+
let (:transparent_img_data) { IO.read(SPEC_ROOT.join('support/transparent_background.png')) }
|
7
8
|
|
8
|
-
context "a pretty picture" do
|
9
|
+
context "a pretty picture" do
|
9
10
|
|
10
11
|
it "basic loading and resizing of an image" do
|
11
12
|
img = Imgry::Processor::ImgScalr.with_bytes(img_data)
|
@@ -22,6 +23,45 @@ if RUBY_ENGINE == 'jruby'
|
|
22
23
|
new_img_blob.length.should == 30319
|
23
24
|
end
|
24
25
|
|
26
|
+
it "crops an image" do
|
27
|
+
img = Imgry::Processor::ImgScalr.with_bytes(img_data)
|
28
|
+
|
29
|
+
img.width.should == 1024
|
30
|
+
img.height.should == 764
|
31
|
+
|
32
|
+
img.crop!("300x200+100+300")
|
33
|
+
img.width.should == 300
|
34
|
+
img.height.should == 200
|
35
|
+
end
|
36
|
+
|
37
|
+
it "handles offsets properly when cropping an image" do
|
38
|
+
img = Imgry::Processor::ImgScalr.with_bytes(img_data)
|
39
|
+
|
40
|
+
img.crop!("300x200+800+600")
|
41
|
+
img.width.should == 224
|
42
|
+
img.height.should == 164
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
context "image format" do
|
48
|
+
|
49
|
+
it "corrects passed in format" do
|
50
|
+
img = Imgry::Processor::ImgScalr.with_bytes(img_data)
|
51
|
+
img.format.should == 'jpg'
|
52
|
+
end
|
53
|
+
|
54
|
+
it "knows how to detect jpg files" do
|
55
|
+
img = Imgry::Processor::ImgScalr.with_bytes(img_data)
|
56
|
+
img.format.should == 'jpg'
|
57
|
+
end
|
58
|
+
|
59
|
+
it "knows how to detect png files" do
|
60
|
+
img = Imgry::Processor::ImgScalr.with_bytes(transparent_img_data)
|
61
|
+
img.format.should == 'png'
|
62
|
+
img.save SPEC_ROOT.join('support/transparent_background_saved.png')
|
63
|
+
end
|
64
|
+
|
25
65
|
end
|
26
66
|
|
27
67
|
end
|
@@ -4,8 +4,7 @@ describe Imgry::Processor::MiniMagick do
|
|
4
4
|
|
5
5
|
let (:img_data) { IO.read(SPEC_ROOT.join('support/335is.jpg')) }
|
6
6
|
|
7
|
-
context "a pretty picture" do
|
8
|
-
|
7
|
+
context "a pretty picture" do
|
9
8
|
it "basic loading and resizing of an image" do
|
10
9
|
img = Imgry::Processor::MiniMagick.with_bytes(img_data)
|
11
10
|
|
@@ -21,6 +20,33 @@ describe Imgry::Processor::MiniMagick do
|
|
21
20
|
new_img_blob.length.should == 32671
|
22
21
|
end
|
23
22
|
|
23
|
+
it "crops an image" do
|
24
|
+
img = Imgry::Processor::MiniMagick.with_bytes(img_data)
|
25
|
+
|
26
|
+
img.width.should == 1024
|
27
|
+
img.height.should == 764
|
28
|
+
|
29
|
+
img.crop!("300x200+100+300")
|
30
|
+
img.width.should == 300
|
31
|
+
img.height.should == 200
|
32
|
+
|
33
|
+
img.save(SPEC_ROOT.join('support/335is_3.jpg'))
|
34
|
+
end
|
35
|
+
|
36
|
+
it "handles offsets properly when cropping an image" do
|
37
|
+
img = Imgry::Processor::MiniMagick.with_bytes(img_data)
|
38
|
+
|
39
|
+
img.crop!("300x200+800+600")
|
40
|
+
img.width.should == 224
|
41
|
+
img.height.should == 164
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "image format" do
|
46
|
+
it "corrects passed in format" do
|
47
|
+
img = Imgry::Processor::MiniMagick.with_bytes(img_data)
|
48
|
+
img.format.should == 'jpg'
|
49
|
+
end
|
24
50
|
end
|
25
51
|
|
26
52
|
end
|
data/spec/imgry_spec.rb
CHANGED
@@ -6,13 +6,31 @@ describe Imgry do
|
|
6
6
|
|
7
7
|
context "a pretty picture" do
|
8
8
|
|
9
|
-
it "
|
9
|
+
it "resizes an image from memory through high level interface" do
|
10
10
|
img = Imgry.with_bytes(img_data)
|
11
11
|
|
12
12
|
img.resize!("300x")
|
13
13
|
img.width.should == 300
|
14
14
|
end
|
15
15
|
|
16
|
+
it "loads from a file and resizes an image" do
|
17
|
+
img = Imgry.from_file(SPEC_ROOT.join('support/335is.png'))
|
18
|
+
img.resize!("400x")
|
19
|
+
img.width.should == 400
|
20
|
+
end
|
21
|
+
|
22
|
+
it "raises error if file is bogus" do
|
23
|
+
expect { Imgry.from_file('hi') }.to raise_error(Imgry::FileUnreadableError)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "writes to a file" do
|
27
|
+
img = Imgry.with_bytes(img_data)
|
28
|
+
tmpfile = Dir.tmpdir+'/imgry.jpg'
|
29
|
+
img.save(tmpfile)
|
30
|
+
File.exists?(tmpfile).should == true
|
31
|
+
File.unlink(tmpfile)
|
32
|
+
end
|
33
|
+
|
16
34
|
end
|
17
35
|
|
18
36
|
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
metadata
CHANGED
@@ -1,32 +1,32 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: imgry
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
5
|
-
prerelease:
|
4
|
+
version: 0.1.4
|
5
|
+
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Pressly
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-12-
|
12
|
+
date: 2012-12-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
|
17
|
-
none: false
|
16
|
+
version_requirements: !ruby/object:Gem::Requirement
|
18
17
|
requirements:
|
19
18
|
- - ~>
|
20
19
|
- !ruby/object:Gem::Version
|
21
20
|
version: '2.12'
|
22
|
-
type: :development
|
23
|
-
prerelease: false
|
24
|
-
version_requirements: !ruby/object:Gem::Requirement
|
25
21
|
none: false
|
22
|
+
requirement: !ruby/object:Gem::Requirement
|
26
23
|
requirements:
|
27
24
|
- - ~>
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '2.12'
|
27
|
+
none: false
|
28
|
+
prerelease: false
|
29
|
+
type: :development
|
30
30
|
description: Fast image resizing/cropping designed for JRuby with MRI support
|
31
31
|
email:
|
32
32
|
- info@pressly.com
|
@@ -34,59 +34,67 @@ executables: []
|
|
34
34
|
extensions: []
|
35
35
|
extra_rdoc_files: []
|
36
36
|
files:
|
37
|
+
- lib/imgry.rb
|
37
38
|
- lib/imgry/geometry.rb
|
39
|
+
- lib/imgry/processor.rb
|
40
|
+
- lib/imgry/version.rb
|
38
41
|
- lib/imgry/processor/image_voodoo.rb
|
39
42
|
- lib/imgry/processor/img_scalr.rb
|
40
43
|
- lib/imgry/processor/java_adapter.rb
|
41
44
|
- lib/imgry/processor/mini_magick.rb
|
42
|
-
- lib/imgry/processor.rb
|
43
|
-
- lib/imgry/version.rb
|
44
|
-
- lib/imgry.rb
|
45
45
|
- lib/java/imgscalr-lib-4.2.jar
|
46
46
|
- README.md
|
47
|
+
- spec/imgry_spec.rb
|
48
|
+
- spec/spec_helper.rb
|
47
49
|
- spec/imgry/geometry_spec.rb
|
48
|
-
- spec/imgry/imgry_spec.rb
|
49
50
|
- spec/imgry/processor/image_voodoo_spec.rb
|
50
51
|
- spec/imgry/processor/img_scalr_spec.rb
|
51
52
|
- spec/imgry/processor/mini_magick_spec.rb
|
52
|
-
- spec/imgry_spec.rb
|
53
|
-
- spec/spec_helper.rb
|
54
53
|
- spec/support/335is.gif
|
55
54
|
- spec/support/335is.jpg
|
56
55
|
- spec/support/335is.png
|
56
|
+
- spec/support/335is_3.jpg
|
57
|
+
- spec/support/cmyk.jpg
|
58
|
+
- spec/support/mexico-cmyk.jpg
|
59
|
+
- spec/support/transparent_background.png
|
60
|
+
- spec/support/transparent_background_saved.png
|
57
61
|
homepage: http://github.com/nulayer/imgry
|
58
62
|
licenses: []
|
59
|
-
post_install_message:
|
63
|
+
post_install_message:
|
60
64
|
rdoc_options: []
|
61
65
|
require_paths:
|
62
66
|
- lib
|
63
67
|
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
-
none: false
|
65
68
|
requirements:
|
66
69
|
- - ! '>='
|
67
70
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
69
|
-
|
71
|
+
version: !binary |-
|
72
|
+
MA==
|
70
73
|
none: false
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
75
|
requirements:
|
72
76
|
- - ! '>='
|
73
77
|
- !ruby/object:Gem::Version
|
74
78
|
version: 1.3.6
|
79
|
+
none: false
|
75
80
|
requirements: []
|
76
|
-
rubyforge_project:
|
81
|
+
rubyforge_project:
|
77
82
|
rubygems_version: 1.8.24
|
78
|
-
signing_key:
|
83
|
+
signing_key:
|
79
84
|
specification_version: 3
|
80
85
|
summary: Fast image resizing/cropping designed for JRuby with MRI support
|
81
86
|
test_files:
|
87
|
+
- spec/imgry_spec.rb
|
88
|
+
- spec/spec_helper.rb
|
82
89
|
- spec/imgry/geometry_spec.rb
|
83
|
-
- spec/imgry/imgry_spec.rb
|
84
90
|
- spec/imgry/processor/image_voodoo_spec.rb
|
85
91
|
- spec/imgry/processor/img_scalr_spec.rb
|
86
92
|
- spec/imgry/processor/mini_magick_spec.rb
|
87
|
-
- spec/imgry_spec.rb
|
88
|
-
- spec/spec_helper.rb
|
89
93
|
- spec/support/335is.gif
|
90
94
|
- spec/support/335is.jpg
|
91
95
|
- spec/support/335is.png
|
92
|
-
|
96
|
+
- spec/support/335is_3.jpg
|
97
|
+
- spec/support/cmyk.jpg
|
98
|
+
- spec/support/mexico-cmyk.jpg
|
99
|
+
- spec/support/transparent_background.png
|
100
|
+
- spec/support/transparent_background_saved.png
|
data/spec/imgry/imgry_spec.rb
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Imgry do
|
4
|
-
|
5
|
-
let (:img_data) { IO.read(SPEC_ROOT.join('support/335is.jpg')) }
|
6
|
-
|
7
|
-
context "a pretty picture" do
|
8
|
-
|
9
|
-
it "resizes an image from memory through high level interface" do
|
10
|
-
img = Imgry.with_bytes(img_data)
|
11
|
-
|
12
|
-
img.resize!("300x")
|
13
|
-
img.width.should == 300
|
14
|
-
end
|
15
|
-
|
16
|
-
it "loads from a file and resizes an image" do
|
17
|
-
img = Imgry.from_file(SPEC_ROOT.join('support/335is.png'))
|
18
|
-
img.resize!("400x")
|
19
|
-
img.width.should == 400
|
20
|
-
end
|
21
|
-
|
22
|
-
it "raises error if file is bogus" do
|
23
|
-
expect { Imgry.from_file('hi') }.to raise_error(Imgry::FileUnreadableError)
|
24
|
-
end
|
25
|
-
|
26
|
-
it "writes to a file" do
|
27
|
-
img = Imgry.with_bytes(img_data)
|
28
|
-
tmpfile = Dir.tmpdir+'/imgry.jpg'
|
29
|
-
img.save(tmpfile)
|
30
|
-
File.exists?(tmpfile).should == true
|
31
|
-
File.unlink(tmpfile)
|
32
|
-
end
|
33
|
-
|
34
|
-
end
|
35
|
-
|
36
|
-
end
|