tinyimg 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a953ed5351abc1984d8739f8ec3d91a1bed9654a
4
+ data.tar.gz: c73c4110056238bc19a1c6e7ae6204b4c98a9968
5
+ SHA512:
6
+ metadata.gz: 810f4ae575ca67c08c7a1551eb0abf4f16ca6fb12c77d4d9dd9227bd448856644d063424c0d34a6251aa2a52ef0be38ad9180e29f05d3e2a81ccb487d7c260b3
7
+ data.tar.gz: f7021348faf7e950ed87c51c12383684238bdfef806fb9f11d36bdb0c1e51c600576bb7fe7ac2ef48f31361d6769ffb50b988166ffabbb625cdf6983e7142560
@@ -0,0 +1,5 @@
1
+ /*.gem
2
+ ext/tinyimg/Makefile
3
+ ext/tinyimg/mkmf.log
4
+ ext/tinyimg/*.bundle
5
+ ext/tinyimg/*.o
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
@@ -0,0 +1,29 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ timyimg (0.1.0)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.2.5)
10
+ rspec (3.3.0)
11
+ rspec-core (~> 3.3.0)
12
+ rspec-expectations (~> 3.3.0)
13
+ rspec-mocks (~> 3.3.0)
14
+ rspec-core (3.3.2)
15
+ rspec-support (~> 3.3.0)
16
+ rspec-expectations (3.3.1)
17
+ diff-lcs (>= 1.2.0, < 2.0)
18
+ rspec-support (~> 3.3.0)
19
+ rspec-mocks (3.3.2)
20
+ diff-lcs (>= 1.2.0, < 2.0)
21
+ rspec-support (~> 3.3.0)
22
+ rspec-support (3.3.0)
23
+
24
+ PLATFORMS
25
+ ruby
26
+
27
+ DEPENDENCIES
28
+ rspec (~> 3.0)
29
+ timyimg!
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright 2015 Roger Nesbitt
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,74 @@
1
+ # Tinyimg
2
+
3
+ Load a JPEG or PNG, get its dimensions, resize it, and extract it again as either a JPEG or PNG.
4
+
5
+ This gem can work from image data stored in memory, as well as from a file or IO stream.
6
+ It's been coded to be as efficient as possible, so doesn't use temporary files.
7
+
8
+ Tinyimg uses libgd for its image processing. libgd is significantly less painful to install than
9
+ ImageMagick and friends! Other than that, all that is required is Ruby 2.0+.
10
+
11
+ ## Installation
12
+
13
+ If you don't already have libgd installed on your system, install it.
14
+
15
+ On OS X, install Homebrew and
16
+
17
+ brew install libgd
18
+
19
+ On a Linux system, use your package manager. For example, on Debian/Ubuntu:
20
+
21
+ sudo apt-get install libgd-dev
22
+
23
+ Then add tinyimg to your project's Gemfile
24
+
25
+ gem 'tinyimg'
26
+
27
+ ## Usage
28
+
29
+ Load the image with the method that fits your use case:
30
+
31
+ image = Tinyimg.from_string(an_image_that_is_already_loaded)
32
+ image = Tinyimg.from_file("some_image.png")
33
+ image = Tinyimg.from_io(params[:uploaded_file])
34
+
35
+ Manipulate it by using one of the resize commands:
36
+
37
+ image.resize_to_fit!(100, 100) # image will be 100x100 maximum
38
+ image.resize_to_fill!(100, 100) # image will be 100x100 minimum
39
+ image.resize!(100, 100) # forces image to be exactly 100x100
40
+
41
+ Then get an image back:
42
+
43
+ image.to_png # returns a string
44
+ image.to_jpeg # returns a string
45
+ image.save("some_image.jpg") # file type auto-determined by extension
46
+
47
+ You can ask for the image's dimensions:
48
+
49
+ image.width # => 120
50
+ image.height # => 80
51
+ image.dimensions # => [120, 80]
52
+
53
+ You can also use the non-! versions of the resize methods: `resize`, `resize_to_fit` and `resize_to_fill`.
54
+ These create a new image in memory and return it, leaving the old image untouched. This is useful if you want
55
+ to resize an original image to multiple sizes. Using these methods will take more memory.
56
+
57
+ ## Examples
58
+
59
+ Take an uploaded file, save the original as a JPEG, then resize to create a thumbnail and save that too:
60
+
61
+ Tinyimg
62
+ .from_io(params[:uploaded_file])
63
+ .save("#{path}/full_size.jpg")
64
+ .resize_to_fit!(100, 100)
65
+ .save("#{path}/thumbnail.jpg")
66
+
67
+ Load a file from disk, make a thumbnail, and return it as a JPEG so we can save it into our database:
68
+
69
+ data = Tinyimg.from_file(image_filename).resize_to_fit!(100, 100).to_jpeg
70
+ user.update!(thumbnail_image: data)
71
+
72
+ ## Author and licence
73
+
74
+ Copyright 2015 Roger Nesbitt. Licenced under the MIT licence.
@@ -0,0 +1,35 @@
1
+ require 'mkmf'
2
+
3
+ def filter_dirs(dirs)
4
+ dirs.select {|dir| Dir.exists?(dir)}
5
+ end
6
+
7
+ def cannot_find_gd
8
+ abort <<-TEXT
9
+ *******************************************************************************
10
+ It looks like libgd is not installed on your system.
11
+
12
+ If you're on OS X, install homebrew and try
13
+ brew install libgd
14
+
15
+ If you're on Debian/Ubuntu linux, try
16
+ apt-get install libgd-dev
17
+ *******************************************************************************
18
+ TEXT
19
+ end
20
+
21
+ header_dirs = %w(/opt/local/include /usr/local/include /usr/include)
22
+ lib_dirs = %w(/opt/local/lib /usr/local/lib /usr/lib)
23
+
24
+ dir_config('gd', filter_dirs(header_dirs), filter_dirs(lib_dirs))
25
+
26
+ have_library('gd', 'gdFree') or cannot_find_gd
27
+ have_header('gd.h') or cannot_find_gd
28
+ have_func('gdImageJpegPtr') or abort "Your libgd is too old! You need at least version 1.8.0, and preferably 2.1.1+."
29
+ have_func('gdImageFile')
30
+ have_func('gdImageCreateFromFile')
31
+ have_func('gdImageAlphaBlending')
32
+ have_func('gdImageClone')
33
+ have_func('gdImagePngPtrEx')
34
+
35
+ create_makefile 'tinyimg/tinyimg'
@@ -0,0 +1,255 @@
1
+ #include <ruby.h>
2
+ #include <gd.h>
3
+
4
+ gdImagePtr get_image_data(VALUE self)
5
+ {
6
+ gdImagePtr image;
7
+ VALUE wrapped_image = rb_iv_get(self, "@data");
8
+ Data_Get_Struct(wrapped_image, struct gdImageStruct, image);
9
+ return image;
10
+ }
11
+
12
+ void set_image_data(VALUE self, gdImagePtr image)
13
+ {
14
+ VALUE klass, value;
15
+
16
+ klass = rb_const_get_at(rb_class_of(self), rb_intern("Image"));
17
+ value = Data_Wrap_Struct(klass, 0, gdImageDestroy, image);
18
+ rb_iv_set(self, "@data", value);
19
+ }
20
+
21
+ void set_alpha(gdImagePtr image)
22
+ {
23
+ #ifdef HAVE_GDIMAGEALPHABLENDING
24
+ gdImageAlphaBlending(image, 0);
25
+ gdImageSaveAlpha(image, 1);
26
+ #endif
27
+ }
28
+
29
+ VALUE retrieve_image_dimensions(VALUE self)
30
+ {
31
+ gdImagePtr image = get_image_data(self);
32
+
33
+ rb_iv_set(self, "@width", INT2FIX(gdImageSX(image)));
34
+ rb_iv_set(self, "@height", INT2FIX(gdImageSY(image)));
35
+
36
+ return Qnil;
37
+ }
38
+
39
+ VALUE load_from_string(VALUE self, VALUE input, VALUE type)
40
+ {
41
+ gdImagePtr image;
42
+ ID type_id;
43
+
44
+ Check_Type(input, T_STRING);
45
+ Check_Type(type, T_SYMBOL);
46
+ type_id = SYM2ID(type);
47
+
48
+ if (type_id == rb_intern("png")) {
49
+ image = gdImageCreateFromPngPtr(RSTRING_LEN(input), RSTRING_PTR(input));
50
+ }
51
+ else if (type_id == rb_intern("jpeg")) {
52
+ image = gdImageCreateFromJpegPtr(RSTRING_LEN(input), RSTRING_PTR(input));
53
+ }
54
+ else {
55
+ rb_raise(rb_eArgError, "type must be a supported image type");
56
+ }
57
+
58
+ if (!image) {
59
+ rb_raise(rb_eRuntimeError, "Error loading image data");
60
+ }
61
+
62
+ set_image_data(self, image);
63
+ set_alpha(image);
64
+
65
+ retrieve_image_dimensions(self);
66
+
67
+ return self;
68
+ }
69
+
70
+ #ifdef HAVE_GDIMAGECREATEFROMFILE
71
+ VALUE load_from_file(VALUE self, VALUE filename)
72
+ {
73
+ gdImagePtr image;
74
+
75
+ Check_Type(filename, T_STRING);
76
+
77
+ image = gdImageCreateFromFile(StringValueCStr(filename));
78
+ if (!image) {
79
+ rb_raise(rb_eRuntimeError, "Error loading image data");
80
+ }
81
+
82
+ set_image_data(self, image);
83
+ set_alpha(image);
84
+
85
+ retrieve_image_dimensions(self);
86
+
87
+ return self;
88
+ }
89
+ #endif
90
+
91
+ VALUE initialize_copy(int argc, VALUE *argv, VALUE self)
92
+ {
93
+ gdImagePtr image, original;
94
+
95
+ rb_call_super(argc, argv);
96
+
97
+ original = get_image_data(self);
98
+
99
+ #ifdef HAVE_GDIMAGECLONE
100
+ image = gdImageClone(original);
101
+ #else
102
+ int width = gdImageSX(original), height = gdImageSY(original);
103
+
104
+ image = gdImageCreateTrueColor(width, height);
105
+ set_alpha(image);
106
+
107
+ gdImageCopy(image, original, 0, 0, 0, 0, width, height);
108
+ #endif
109
+
110
+ set_image_data(self, image);
111
+
112
+ return Qnil;
113
+ }
114
+
115
+ #ifdef HAVE_GDIMAGEFILE
116
+ VALUE save_to_file(VALUE self, VALUE filename)
117
+ {
118
+ gdImagePtr image;
119
+ int result;
120
+
121
+ Check_Type(filename, T_STRING);
122
+
123
+ image = get_image_data(self);
124
+ result = gdImageFile(image, StringValueCStr(filename));
125
+
126
+ if (result == GD_FALSE) {
127
+ rb_raise(rb_eRuntimeError, "Unknown error occurred while trying to save the file; check it is using a known filename");
128
+ }
129
+
130
+ return self;
131
+ }
132
+ #endif
133
+
134
+ VALUE to_jpeg(int argc, VALUE *argv, VALUE self)
135
+ {
136
+ gdImagePtr image;
137
+ char *image_data;
138
+ int size, quality;
139
+ VALUE quality_value;
140
+
141
+ rb_scan_args(argc, argv, "01", &quality_value);
142
+
143
+ if (NIL_P(quality_value)) {
144
+ quality = -1;
145
+ }
146
+ else {
147
+ Check_Type(quality_value, T_FIXNUM);
148
+ quality = FIX2INT(quality_value);
149
+ }
150
+
151
+ if (quality < -1 || quality > 100) {
152
+ rb_raise(rb_eArgError, "Quality must be between 0 and 100, or -1 for default");
153
+ }
154
+
155
+ image = get_image_data(self);
156
+
157
+ image_data = (char *) gdImageJpegPtr(image, &size, quality);
158
+ if (!image_data) {
159
+ rb_raise(rb_eRuntimeError, "Unknown error occurred while trying to build a JPEG");
160
+ }
161
+
162
+ VALUE output = rb_str_new(image_data, size);
163
+ gdFree(image_data);
164
+ return output;
165
+ }
166
+
167
+ VALUE to_png(int argc, VALUE *argv, VALUE self)
168
+ {
169
+ gdImagePtr image;
170
+ char *image_data;
171
+ int size;
172
+ VALUE compression_value;
173
+ int compression;
174
+
175
+ rb_scan_args(argc, argv, "01", &compression_value);
176
+
177
+ image = get_image_data(self);
178
+
179
+ if (NIL_P(compression_value)) {
180
+ image_data = (char *) gdImagePngPtr(image, &size);
181
+ }
182
+ else {
183
+ Check_Type(compression_value, T_FIXNUM);
184
+ compression = FIX2INT(compression_value);
185
+
186
+ if (compression < 0 || compression > 9) {
187
+ rb_raise(rb_eArgError, "Compression must be between 0 and 9");
188
+ }
189
+
190
+ #ifdef HAVE_GDIMAGEPNGPTREX
191
+ image_data = (char *) gdImagePngPtrEx(image, &size, compression);
192
+ #else
193
+ image_data = (char *) gdImagePngPtr(image, &size);
194
+ #endif
195
+ }
196
+
197
+ if (!image_data) {
198
+ rb_raise(rb_eRuntimeError, "Unknown error occurred while trying to build a PNG");
199
+ }
200
+
201
+ VALUE output = rb_str_new(image_data, size);
202
+ gdFree(image_data);
203
+ return output;
204
+ }
205
+
206
+ VALUE resize_bang(VALUE self, VALUE width_value, VALUE height_value)
207
+ {
208
+ gdImagePtr image_in, image_out;
209
+ int width, height;
210
+
211
+ Check_Type(width_value, T_FIXNUM);
212
+ Check_Type(height_value, T_FIXNUM);
213
+
214
+ width = FIX2INT(width_value);
215
+ height = FIX2INT(height_value);
216
+
217
+ if (width < 0 || height < 0) {
218
+ rb_raise(rb_eArgError, "width and height must both be positive integers");
219
+ }
220
+
221
+ image_in = get_image_data(self);
222
+ image_out = gdImageCreateTrueColor(width, height);
223
+ set_alpha(image_out);
224
+
225
+ gdImageCopyResampled(
226
+ image_out, image_in, 0, 0, 0, 0,
227
+ gdImageSX(image_out), gdImageSY(image_out),
228
+ gdImageSX(image_in), gdImageSY(image_in)
229
+ );
230
+
231
+ set_image_data(self, image_out);
232
+
233
+ retrieve_image_dimensions(self);
234
+
235
+ return self;
236
+ }
237
+
238
+ void Init_tinyimg()
239
+ {
240
+ VALUE cTinyimg = rb_define_class("Tinyimg", rb_cObject);
241
+ rb_define_class_under(cTinyimg, "Image", rb_cObject);
242
+
243
+ rb_define_method(cTinyimg, "resize!", resize_bang, 2);
244
+ rb_define_method(cTinyimg, "to_jpeg", to_jpeg, -1);
245
+ rb_define_method(cTinyimg, "to_png", to_png, -1);
246
+ rb_define_private_method(cTinyimg, "initialize_copy", initialize_copy, -1);
247
+ rb_define_private_method(cTinyimg, "load_from_string", load_from_string, 2);
248
+ rb_define_private_method(cTinyimg, "retrieve_image_dimensions", retrieve_image_dimensions, 0);
249
+ #ifdef HAVE_GDIMAGECREATEFROMFILE
250
+ rb_define_private_method(cTinyimg, "load_from_file", load_from_file, 1);
251
+ #endif
252
+ #ifdef HAVE_GDIMAGEFILE
253
+ rb_define_private_method(cTinyimg, "save_to_file", save_to_file, 1);
254
+ #endif
255
+ }
@@ -0,0 +1,138 @@
1
+ require_relative '../ext/tinyimg/tinyimg'
2
+
3
+ class Tinyimg
4
+ attr_reader :width, :height
5
+
6
+ private_class_method :new
7
+
8
+ def self.from_file(filename)
9
+ new(:filename, filename)
10
+ end
11
+
12
+ def self.from_io(io)
13
+ from_string(io.read)
14
+ end
15
+
16
+ def self.from_string(data)
17
+ new(:string, data)
18
+ end
19
+
20
+ def dimensions
21
+ [width, height]
22
+ end
23
+
24
+ def resize(width, height)
25
+ dup.resize!(width, height)
26
+ end
27
+
28
+ # Implemented in C
29
+ # def resize!(width, height)
30
+ # end
31
+
32
+ def resize_to_fit(new_width, new_height)
33
+ dup.resize_to_fit!(new_width, new_height)
34
+ end
35
+
36
+ def resize_to_fit!(new_width, new_height)
37
+ resize_to_fit_or_fill!(new_width, new_height) do |old_ratio, new_ratio|
38
+ old_ratio > new_ratio
39
+ end
40
+ end
41
+
42
+ def resize_to_fill(new_width, new_height)
43
+ dup.resize_to_fill!(new_width, new_height)
44
+ end
45
+
46
+ def resize_to_fill!(new_width, new_height)
47
+ resize_to_fit_or_fill!(new_width, new_height) do |old_ratio, new_ratio|
48
+ old_ratio < new_ratio
49
+ end
50
+ end
51
+
52
+ def save(filename)
53
+ if respond_to?(:save_to_file)
54
+ save_to_file(filename)
55
+ else
56
+ data = case determine_by_extension(filename)
57
+ when :jpeg then to_jpeg
58
+ when :png then to_png
59
+ end
60
+
61
+ File.write(filename, data)
62
+ end
63
+ end
64
+
65
+ # Implemented in C
66
+ # def to_jpeg(quality = DEFAULT_JPEG_QUALITY)
67
+ # end
68
+
69
+ # Implemented in C
70
+ # def to_png(compression = nil)
71
+ # end
72
+
73
+ private
74
+
75
+ def initialize(mode, data, type = nil)
76
+ case mode
77
+ when :string
78
+ load_from_string(data, determine_type(data))
79
+ when :filename
80
+ if respond_to?(:load_from_file)
81
+ load_from_file(data)
82
+ else
83
+ content = File.read(data)
84
+ load_from_string(content, determine_type(content))
85
+ end
86
+ else
87
+ raise
88
+ end
89
+ end
90
+
91
+ def resize_to_fit_or_fill!(new_width, new_height)
92
+ old_ratio = width / height.to_f
93
+ new_ratio = new_width / new_height.to_f
94
+
95
+ if yield(old_ratio, new_ratio)
96
+ resize_width = new_width
97
+ resize_height = (height * (new_width / width.to_f)).to_i
98
+ else
99
+ resize_width = (width * (new_height / height.to_f)).to_i
100
+ resize_height = new_height
101
+ end
102
+
103
+ resize!(resize_width, resize_height)
104
+ end
105
+
106
+ def determine_type(data)
107
+ if data[0, 3].unpack("C*") == [255, 216, 255]
108
+ :jpeg
109
+ elsif data[0, 8].unpack("C*") == [137, 80, 78, 71, 13, 10, 26, 10]
110
+ :png
111
+ else
112
+ raise ArgumentError, "Only JPEG and PNG files are supported"
113
+ end
114
+ end
115
+
116
+ def determine_by_extension(filename)
117
+ case filename.split(".").last.to_s.downcase
118
+ when 'jpeg', 'jpg' then :jpeg
119
+ when 'png' then :png
120
+ else
121
+ raise ArgumentError, "Cannot determine image type based on the filename"
122
+ end
123
+ end
124
+
125
+ # Implemented in C
126
+ # def load_from_string(data, type)
127
+ # end
128
+
129
+ # Implemented in C
130
+ # Only available with libgd 2.1.1+
131
+ # def load_from_file(filename)
132
+ # end
133
+
134
+ # Implemented in C
135
+ # Only available with libgd 2.1.1+
136
+ # def save_to_file(filename)
137
+ # end
138
+ end
Binary file
@@ -0,0 +1,122 @@
1
+ require 'tinyimg'
2
+
3
+ RSpec.describe Tinyimg do
4
+ let(:samples_directory) { "#{File.dirname(__FILE__)}/samples" }
5
+ let(:sample_filename) { "#{samples_directory}/duck.png" }
6
+ let(:sample) { Tinyimg.from_file(sample_filename) }
7
+
8
+ let(:tmp_directory) { "#{File.dirname(__FILE__)}/tmp" }
9
+ let(:tmp_jpg_filename) { "#{tmp_directory}/test.jpg" }
10
+ let(:tmp_png_filename) { "#{tmp_directory}/test.png" }
11
+
12
+ describe "#from_file, #width, #height and #dimensions" do
13
+ it "loads from a file and returns the width and height of the image" do
14
+ expect(sample.width).to eq 200
15
+ expect(sample.height).to eq 153
16
+ expect(sample.dimensions).to eq [200, 153]
17
+ end
18
+ end
19
+
20
+ describe "#from_string" do
21
+ it "loads a PNG" do
22
+ image = Tinyimg.from_string(IO.read(sample_filename))
23
+ expect(image.dimensions).to eq [200, 153]
24
+ end
25
+ end
26
+
27
+ describe "#from_io" do
28
+ it "loads a PNG" do
29
+ File.open(sample_filename, "r") do |file|
30
+ image = Tinyimg.from_io(file)
31
+ expect(image.dimensions).to eq [200, 153]
32
+ end
33
+ end
34
+ end
35
+
36
+ describe "#resize" do
37
+ it "resizes the image as requested, creating a new image" do
38
+ result = sample.resize(100, 100)
39
+ expect(result).to_not eql sample
40
+ expect(sample.dimensions).to eq [200, 153]
41
+ expect(result.dimensions).to eq [100, 100]
42
+ end
43
+ end
44
+
45
+ describe "#resize!" do
46
+ it "resizes the image as requested" do
47
+ result = sample.resize!(100, 100)
48
+ expect(result).to eql sample
49
+ expect(sample.dimensions).to eq [100, 100]
50
+ end
51
+ end
52
+
53
+ describe "#resize_to_fit!" do
54
+ it "calculates the image dimensions so it fits the width and resizes" do
55
+ sample.resize_to_fit!(100, 100)
56
+ expect(sample.dimensions).to eq [100, 76]
57
+ end
58
+
59
+ it "calculates the image dimensions so it fits the height and resizes" do
60
+ sample.resize_to_fit!(1000, 100)
61
+ expect(sample.dimensions).to eq [130, 100]
62
+ end
63
+ end
64
+
65
+ describe "#resize_to_fill!" do
66
+ it "calculates the image dimensions so it fills the width and resizes" do
67
+ sample.resize_to_fill!(1000, 100)
68
+ expect(sample.dimensions).to eq [1000, 765]
69
+ end
70
+
71
+ it "calculates the image dimensions so it fills the height and resizes" do
72
+ sample.resize_to_fill!(100, 100)
73
+ expect(sample.dimensions).to eq [130, 100]
74
+ end
75
+ end
76
+
77
+ describe "#save" do
78
+ it "saves a JPEG" do
79
+ begin
80
+ sample.save(tmp_jpg_filename)
81
+ expect(File.read(tmp_jpg_filename, 3).unpack("C*")).to eq [255, 216, 255]
82
+
83
+ reloaded = Tinyimg.from_file(tmp_jpg_filename)
84
+ expect(reloaded.dimensions).to eq [200, 153]
85
+ ensure
86
+ File.unlink(tmp_jpg_filename)
87
+ end
88
+ end
89
+
90
+ it "saves a PNG" do
91
+ begin
92
+ sample.save(tmp_png_filename)
93
+ expect(File.read(tmp_png_filename, 3).unpack("C*")).to eq [137, 80, 78]
94
+
95
+ reloaded = Tinyimg.from_file(tmp_png_filename)
96
+ expect(reloaded.dimensions).to eq [200, 153]
97
+ ensure
98
+ File.unlink(tmp_png_filename)
99
+ end
100
+ end
101
+ end
102
+
103
+ describe "#to_jpeg" do
104
+ it "exports a JPEG" do
105
+ data = sample.to_jpeg
106
+ expect(data[0, 3].unpack("C*")).to eq [255, 216, 255]
107
+
108
+ reloaded = Tinyimg.from_string(data)
109
+ expect(reloaded.dimensions).to eq [200, 153]
110
+ end
111
+ end
112
+
113
+ describe "#to_png" do
114
+ it "exports a PNG" do
115
+ data = sample.to_png
116
+ expect(data[0, 3].unpack("C*")).to eq [137, 80, 78]
117
+
118
+ reloaded = Tinyimg.from_string(data)
119
+ expect(reloaded.dimensions).to eq [200, 153]
120
+ end
121
+ end
122
+ end
File without changes
@@ -0,0 +1,20 @@
1
+ Gem::Specification.new do |gem|
2
+ gem.name = 'tinyimg'
3
+ gem.version = '0.1.0'
4
+ gem.summary = "Tiny and fast JPEG/PNG resizer and converter"
5
+ gem.description = "Convert between JPEG/PNG and resize images, either all in memory or via disk. Only required libgd to function."
6
+ gem.has_rdoc = false
7
+ gem.author = "Roger Nesbitt"
8
+ gem.email = "roger@seriousorange.com"
9
+ gem.homepage = "http://github.com/mogest/tinyimg"
10
+ gem.license = 'MIT'
11
+
12
+ gem.files = `git ls-files`.split("\n")
13
+ gem.test_files = `git ls-files -- spec/*`.split("\n")
14
+ gem.require_paths = ["lib"]
15
+ gem.extensions = %w(ext/tinyimg/extconf.rb)
16
+
17
+ gem.required_ruby_version = '>= 2.0.0'
18
+
19
+ gem.add_development_dependency "rspec", "~> 3.0"
20
+ end
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tinyimg
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Roger Nesbitt
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-11-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ description: Convert between JPEG/PNG and resize images, either all in memory or via
28
+ disk. Only required libgd to function.
29
+ email: roger@seriousorange.com
30
+ executables: []
31
+ extensions:
32
+ - ext/tinyimg/extconf.rb
33
+ extra_rdoc_files: []
34
+ files:
35
+ - ".gitignore"
36
+ - Gemfile
37
+ - Gemfile.lock
38
+ - LICENSE
39
+ - README.md
40
+ - ext/tinyimg/extconf.rb
41
+ - ext/tinyimg/tinyimg.c
42
+ - lib/tinyimg.rb
43
+ - spec/samples/duck.png
44
+ - spec/tinyimg_spec.rb
45
+ - spec/tmp/.keep
46
+ - tinyimg.gemspec
47
+ homepage: http://github.com/mogest/tinyimg
48
+ licenses:
49
+ - MIT
50
+ metadata: {}
51
+ post_install_message:
52
+ rdoc_options: []
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: 2.0.0
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ requirements: []
66
+ rubyforge_project:
67
+ rubygems_version: 2.2.2
68
+ signing_key:
69
+ specification_version: 4
70
+ summary: Tiny and fast JPEG/PNG resizer and converter
71
+ test_files:
72
+ - spec/samples/duck.png
73
+ - spec/tinyimg_spec.rb
74
+ - spec/tmp/.keep