image_size 3.0.2 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.markdown +10 -0
- data/README.markdown +52 -2
- data/image_size.gemspec +2 -2
- data/lib/image_size/uri_reader.rb +83 -47
- data/lib/image_size.rb +17 -0
- data/spec/image_size/chunky_reader_spec.rb +5 -3
- data/spec/image_size_spec.rb +72 -15
- data/spec/images/emf/74x77.emf +0 -0
- data/spec/images/emf/77x77.emf +0 -0
- data/spec/test_server.rb +61 -0
- metadata +12 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f086d46fca698649fed0a23adca9dc67e1fa3317d9f3c209f1fe7f07fcd2cb6b
|
4
|
+
data.tar.gz: ff8f5243aadd37691eb7dabaa7e4b0d3b6fb212aba286a10d86165dc174eabff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6ff23aa12846de6eaeb9a8ae02cde4a152f891e863056cf901732ef1c6cd1a580befab1cb62037feed500906901018cf8cdb64b63dd6538c07f0b84c5e8ce80e
|
7
|
+
data.tar.gz: fe6d488afbac72d4a8c16e3d1457c9ae3acf82b87ac9bd6df34e4077f0a0166c47862eac796f71e34084bb7c1314e49f79963eba41ad73de935232b2f2c35bd1
|
data/CHANGELOG.markdown
CHANGED
@@ -2,6 +2,15 @@
|
|
2
2
|
|
3
3
|
## unreleased
|
4
4
|
|
5
|
+
## v3.2.0 (2022-11-03)
|
6
|
+
|
7
|
+
* Support `EMF` images [#21](https://github.com/toy/image_size/pull/21) [@opoudjis](https://github.com/opoudjis)
|
8
|
+
|
9
|
+
## v3.1.0 (2022-09-17)
|
10
|
+
|
11
|
+
* Document experimental fetching from http server [#18](https://github.com/toy/image_size/issues/18) [@toy](https://github.com/toy)
|
12
|
+
* Improve experimental fetching of image meta from http server by reading only required amount of data when server does not support range header [@toy](https://github.com/toy)
|
13
|
+
|
5
14
|
## v3.0.2 (2022-05-19)
|
6
15
|
|
7
16
|
* Fix handling empty files [#20](https://github.com/toy/image_size/issues/20) [@toy](https://github.com/toy)
|
@@ -15,6 +24,7 @@
|
|
15
24
|
* Read only required chunks of data for files and seekable IOs [@toy](https://github.com/toy)
|
16
25
|
* Raise `FormatError` whenever reading data returns less data than expected [#12](https://github.com/toy/image_size/issues/12) [@toy](https://github.com/toy)
|
17
26
|
* Add `w`/`width` and `h`/`height` accessors to `Size` [@toy](https://github.com/toy)
|
27
|
+
* Experimental efficient fetching of image meta from http server supporting range [@toy](https://github.com/toy)
|
18
28
|
|
19
29
|
## v2.1.2 (2021-08-21)
|
20
30
|
|
data/README.markdown
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
[![Gem Version](https://img.shields.io/gem/v/image_size?logo=rubygems)](https://rubygems.org/gems/image_size)
|
2
2
|
[![Build Status](https://img.shields.io/github/workflow/status/toy/image_size/check/master?logo=github)](https://github.com/toy/image_size/actions/workflows/check.yml)
|
3
|
+
[![Rubocop](https://img.shields.io/github/workflow/status/toy/image_size/rubocop/master?label=rubocop&logo=rubocop)](https://github.com/toy/image_size/actions/workflows/rubocop.yml)
|
3
4
|
|
4
5
|
# image_size
|
5
6
|
|
6
7
|
Measure image size using pure Ruby.
|
7
|
-
Formats: `apng`, `bmp`, `cur`, `gif`, `ico`, `j2c`, `jp2`, `jpeg`, `jpx`, `mng`, `pam`, `pbm`, `pcx`, `pgm`, `png`, `ppm`, `psd`, `svg`, `swf`, `tiff`, `webp`, `xbm`, `xpm`.
|
8
|
+
Formats: `apng`, `bmp`, `cur`, `emf`, `gif`, `ico`, `j2c`, `jp2`, `jpeg`, `jpx`, `mng`, `pam`, `pbm`, `pcx`, `pgm`, `png`, `ppm`, `psd`, `svg`, `swf`, `tiff`, `webp`, `xbm`, `xpm`.
|
8
9
|
|
9
10
|
## Installation
|
10
11
|
|
@@ -53,7 +54,7 @@ require 'image_size'
|
|
53
54
|
image_size = ImageSize.new(ARGF)
|
54
55
|
```
|
55
56
|
|
56
|
-
Works with `open-uri
|
57
|
+
Works with `open-uri`, see [experimental HTTP server interface below](#experimental-fetch-image-meta-from-http-server):
|
57
58
|
|
58
59
|
```ruby
|
59
60
|
require 'image_size'
|
@@ -89,6 +90,55 @@ File.open('spec/images/jpeg/436x429.jpeg', 'rb') do |fh|
|
|
89
90
|
end
|
90
91
|
```
|
91
92
|
|
93
|
+
### Experimental: fetch image meta from HTTP server
|
94
|
+
|
95
|
+
If server recognises Range header, only needed chunks will be fetched even for TIFF images, otherwise required amount
|
96
|
+
of data will be fetched, in most cases first few kilobytes (TIFF images is an exception).
|
97
|
+
|
98
|
+
```ruby
|
99
|
+
require 'image_size'
|
100
|
+
require 'image_size/uri_reader'
|
101
|
+
|
102
|
+
url = 'http://upload.wikimedia.org/wikipedia/commons/b/b4/Mardin_1350660_1350692_33_images.jpg'
|
103
|
+
p ImageSize.url(url).size
|
104
|
+
```
|
105
|
+
|
106
|
+
This interface is as fast as dedicated gem fastimage for images with meta information in the header:
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
url = 'http://upload.wikimedia.org/wikipedia/commons/b/b4/Mardin_1350660_1350692_33_images.jpg'
|
110
|
+
puts Benchmark.measure{ p FastImage.size(url) }
|
111
|
+
```
|
112
|
+
```
|
113
|
+
[9545, 6623]
|
114
|
+
0.004176 0.001974 0.006150 ( 0.282889)
|
115
|
+
```
|
116
|
+
```ruby
|
117
|
+
puts Benchmark.measure{ p ImageSize.url(url).size }
|
118
|
+
```
|
119
|
+
```
|
120
|
+
[9545, 6623]
|
121
|
+
0.005604 0.001406 0.007010 ( 0.238629)
|
122
|
+
```
|
123
|
+
|
124
|
+
And considerably faster for images with meta information at the end of file:
|
125
|
+
|
126
|
+
```ruby
|
127
|
+
url = "https://upload.wikimedia.org/wikipedia/commons/c/c7/Curiosity%27s_Vehicle_System_Test_Bed_%28VSTB%29_Rover_%28PIA15876%29.tif"
|
128
|
+
puts Benchmark.measure{ p FastImage.size(url) }
|
129
|
+
```
|
130
|
+
```
|
131
|
+
[7360, 4912]
|
132
|
+
0.331284 0.247295 0.578579 ( 6.027051)
|
133
|
+
```
|
134
|
+
```ruby
|
135
|
+
puts Benchmark.measure{ p ImageSize.url(url).size }
|
136
|
+
```
|
137
|
+
```
|
138
|
+
[7360, 4912]
|
139
|
+
0.006247 0.001045 0.007292 ( 0.197631)
|
140
|
+
```
|
141
|
+
|
92
142
|
## Licence
|
93
143
|
|
94
144
|
This code is free to use under the terms of the [Ruby's licence](LICENSE.txt).
|
data/image_size.gemspec
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = 'image_size'
|
5
|
-
s.version = '3.0
|
5
|
+
s.version = '3.2.0'
|
6
6
|
s.summary = %q{Measure image size using pure Ruby}
|
7
|
-
s.description = %q{Measure following file dimensions: apng, bmp, cur, gif, ico, j2c, jp2, jpeg, jpx, mng, pam, pbm, pcx, pgm, png, ppm, psd, svg, swf, tiff, webp, xbm, xpm}
|
7
|
+
s.description = %q{Measure following file dimensions: apng, bmp, cur, emf, gif, ico, j2c, jp2, jpeg, jpx, mng, pam, pbm, pcx, pgm, png, ppm, psd, svg, swf, tiff, webp, xbm, xpm}
|
8
8
|
s.homepage = "https://github.com/toy/#{s.name}"
|
9
9
|
s.authors = ['Keisuke Minami', 'Ivan Kuchin']
|
10
10
|
s.license = 'Ruby'
|
@@ -6,67 +6,103 @@ require 'image_size/chunky_reader'
|
|
6
6
|
require 'net/https'
|
7
7
|
require 'uri'
|
8
8
|
|
9
|
-
#
|
9
|
+
# Experimental, not yet part of stable API
|
10
10
|
#
|
11
|
-
# It adds ability to fetch
|
12
|
-
# needed chunks if the server recognises Range header
|
11
|
+
# It adds ability to fetch image meta from HTTP server while downloading only
|
12
|
+
# needed chunks if the server recognises Range header, otherwise fetches only
|
13
|
+
# required amount of data
|
13
14
|
class ImageSize
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
def initialize(uri, redirects = 5)
|
18
|
-
if !@http || @http.address != uri.host || @http.port != uri.port
|
19
|
-
@http.finish if @http
|
20
|
-
@http = Net::HTTP.new(uri.host, uri.port)
|
21
|
-
@http.use_ssl = true if uri.scheme == 'https'
|
22
|
-
@http.start
|
23
|
-
end
|
15
|
+
module URIReader # :nodoc:
|
16
|
+
module HTTPChunkyReader # :nodoc:
|
17
|
+
include ChunkyReader
|
24
18
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
case response
|
29
|
-
when Net::HTTPRedirection
|
30
|
-
raise "Too many redirects: #{response['location']}" unless redirects > 0
|
31
|
-
|
32
|
-
initialize(uri + response['location'], redirects - 1)
|
33
|
-
when Net::HTTPOK
|
34
|
-
@body = response.body
|
35
|
-
when Net::HTTPPartialContent
|
36
|
-
@chunks = { 0 => response.body }
|
37
|
-
when Net::HTTPRequestedRangeNotSatisfiable
|
38
|
-
@body = ''
|
39
|
-
else
|
40
|
-
raise "Unexpected response: #{response}"
|
19
|
+
def chunk_range_header(i)
|
20
|
+
{ 'Range' => "bytes=#{chunk_size * i}-#{(chunk_size * (i + 1)) - 1}" }
|
41
21
|
end
|
42
22
|
end
|
43
23
|
|
44
|
-
|
45
|
-
|
24
|
+
class BodyReader # :nodoc:
|
25
|
+
include ChunkyReader
|
26
|
+
|
27
|
+
def initialize(response)
|
28
|
+
@body = String.new
|
29
|
+
@body_reader = response.to_enum(:read_body)
|
30
|
+
end
|
31
|
+
|
32
|
+
def [](offset, length)
|
33
|
+
if @body_reader
|
34
|
+
begin
|
35
|
+
@body << @body_reader.next while @body.length < offset + length
|
36
|
+
rescue StopIteration, IOError
|
37
|
+
@body_reader = nil
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
46
41
|
@body[offset, length]
|
47
|
-
else
|
48
|
-
super
|
49
42
|
end
|
50
43
|
end
|
51
44
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
raise "Unexpected response: #{response}"
|
60
|
-
end
|
45
|
+
class RangeReader # :nodoc:
|
46
|
+
include HTTPChunkyReader
|
47
|
+
|
48
|
+
def initialize(http, request_uri, chunk0)
|
49
|
+
@http = http
|
50
|
+
@request_uri = request_uri
|
51
|
+
@chunks = { 0 => chunk0 }
|
61
52
|
end
|
62
53
|
|
63
|
-
|
54
|
+
def chunk(i)
|
55
|
+
unless @chunks.key?(i)
|
56
|
+
response = @http.get(@request_uri, chunk_range_header(i))
|
57
|
+
case response
|
58
|
+
when Net::HTTPPartialContent
|
59
|
+
@chunks[i] = response.body
|
60
|
+
else
|
61
|
+
raise "Unexpected response: #{response}"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
@chunks[i]
|
66
|
+
end
|
64
67
|
end
|
65
68
|
|
66
|
-
|
69
|
+
class << self
|
70
|
+
include HTTPChunkyReader
|
71
|
+
|
72
|
+
def open(uri, max_redirects = 5)
|
73
|
+
http = nil
|
74
|
+
(max_redirects + 1).times do
|
75
|
+
unless http && http.address == uri.host && http.port == uri.port
|
76
|
+
http.finish if http
|
77
|
+
|
78
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
79
|
+
http.use_ssl = true if uri.scheme == 'https'
|
80
|
+
http.start
|
81
|
+
end
|
67
82
|
|
68
|
-
|
69
|
-
|
83
|
+
response = http.request_get(uri.request_uri, chunk_range_header(0)) do |response_with_unread_body|
|
84
|
+
case response_with_unread_body
|
85
|
+
when Net::HTTPOK
|
86
|
+
return yield BodyReader.new(response_with_unread_body)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
case response
|
91
|
+
when Net::HTTPRedirection
|
92
|
+
uri += response['location']
|
93
|
+
when Net::HTTPPartialContent
|
94
|
+
return yield RangeReader.new(http, uri.request_uri, response.body)
|
95
|
+
when Net::HTTPRequestedRangeNotSatisfiable
|
96
|
+
return yield StringReader.new('')
|
97
|
+
else
|
98
|
+
raise "Unexpected response: #{response}"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
raise "Too many redirects: #{uri}"
|
103
|
+
ensure
|
104
|
+
http.finish if http.started?
|
105
|
+
end
|
70
106
|
end
|
71
107
|
end
|
72
108
|
|
@@ -74,7 +110,7 @@ class ImageSize
|
|
74
110
|
class << self
|
75
111
|
def open_with_uri(input, &block)
|
76
112
|
if input.is_a?(URI)
|
77
|
-
|
113
|
+
URIReader.open(input, &block)
|
78
114
|
else
|
79
115
|
open_without_uri(input, &block)
|
80
116
|
end
|
data/lib/image_size.rb
CHANGED
@@ -95,6 +95,7 @@ private
|
|
95
95
|
when head[0, 4] == "\0\0\2\0" then :cur
|
96
96
|
when head[0, 12] == "\0\0\0\fjP \r\n\207\n" then detect_jpeg2000_type(ir)
|
97
97
|
when head[0, 4] == "\377O\377Q" then :j2c
|
98
|
+
when head[0, 4] == "\1\0\0\0" && head[40, 4] == ' EMF' then :emf
|
98
99
|
end
|
99
100
|
end
|
100
101
|
|
@@ -374,4 +375,20 @@ private
|
|
374
375
|
def size_of_j2c(ir)
|
375
376
|
ir.unpack(8, 8, 'NN')
|
376
377
|
end
|
378
|
+
|
379
|
+
EMF_UMAX = 256**4
|
380
|
+
EMF_SMAX = EMF_UMAX / 2
|
381
|
+
|
382
|
+
def size_of_emf(ir)
|
383
|
+
left, top, right, bottom =
|
384
|
+
if RUBY_VERSION < '1.9'
|
385
|
+
ir.unpack(24, 16, 'V*').map{ |u| u < EMF_SMAX ? u : u - EMF_UMAX }
|
386
|
+
else
|
387
|
+
ir.unpack(24, 16, 'L<*')
|
388
|
+
end
|
389
|
+
dpi = self.class.dpi
|
390
|
+
[right - left + 1, bottom - top + 1].map do |n|
|
391
|
+
(n.to_f * dpi / 2540).round
|
392
|
+
end
|
393
|
+
end
|
377
394
|
end
|
@@ -56,9 +56,11 @@ describe ImageSize::ChunkyReader do
|
|
56
56
|
offsets.each do |offset_b|
|
57
57
|
length = offset_b - offset
|
58
58
|
expect(reader[offset, length]).to eq(data[offset, length]),
|
59
|
-
|
60
|
-
|
61
|
-
|
59
|
+
[
|
60
|
+
"for offset #{offset} and length #{length}",
|
61
|
+
"expected: #{data[offset, length].inspect}",
|
62
|
+
" got: #{reader[offset, length].inspect}",
|
63
|
+
].join("\n")
|
62
64
|
end
|
63
65
|
end
|
64
66
|
end
|
data/spec/image_size_spec.rb
CHANGED
@@ -7,24 +7,36 @@ require 'image_size/uri_reader'
|
|
7
7
|
|
8
8
|
require 'tempfile'
|
9
9
|
require 'shellwords'
|
10
|
-
|
10
|
+
|
11
|
+
require 'test_server'
|
11
12
|
|
12
13
|
describe ImageSize do
|
13
14
|
before :all do
|
14
|
-
@server =
|
15
|
-
:Logger => WEBrick::Log.new(StringIO.new),
|
16
|
-
:AccessLog => [],
|
17
|
-
:BindAddress => '127.0.0.1',
|
18
|
-
:Port => 0, # get the next available port
|
19
|
-
:DocumentRoot => '.',
|
20
|
-
})
|
21
|
-
@server_thread = Thread.new{ @server.start }
|
22
|
-
@server_base_url = URI("http://127.0.0.1:#{@server.config[:Port]}/")
|
15
|
+
@server = TestServer.new
|
23
16
|
end
|
24
17
|
|
25
18
|
after :all do
|
26
|
-
@server.
|
27
|
-
|
19
|
+
@server.finish
|
20
|
+
end
|
21
|
+
|
22
|
+
def supported_formats
|
23
|
+
ImageSize.private_instance_methods.map{ |name| name[/\Asize_of_(.*)\z/, 1] }.compact.sort
|
24
|
+
end
|
25
|
+
|
26
|
+
describe 'README' do
|
27
|
+
let(:readme){ File.read('README.markdown') }
|
28
|
+
|
29
|
+
it 'lists all supported formats' do
|
30
|
+
expect(readme[/^Formats: .*$/]).to eq("Formats: #{supported_formats.map{ |format| "`#{format}`" }.join(', ')}.")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe 'gemspec' do
|
35
|
+
let(:gemspec){ Gem::Specification.load('image_size.gemspec') }
|
36
|
+
|
37
|
+
it 'lists all supported formats in description' do
|
38
|
+
expect(gemspec.description).to eq("Measure following file dimensions: #{supported_formats.join(', ')}")
|
39
|
+
end
|
28
40
|
end
|
29
41
|
|
30
42
|
Dir['spec/**/*'].each do |path|
|
@@ -131,9 +143,54 @@ describe ImageSize do
|
|
131
143
|
end
|
132
144
|
|
133
145
|
context 'fetching from webserver' do
|
134
|
-
|
135
|
-
|
136
|
-
|
146
|
+
let(:file_url){ @server.base_url + path }
|
147
|
+
|
148
|
+
context 'supporting range' do
|
149
|
+
context 'without redirects' do
|
150
|
+
it 'gets format and dimensions' do
|
151
|
+
image_size = ImageSize.url(file_url)
|
152
|
+
expect(image_size).to have_attributes(attributes)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
context 'with redirects' do
|
157
|
+
it 'gets format and dimensions' do
|
158
|
+
image_size = ImageSize.url("#{file_url}?redirect=5")
|
159
|
+
expect(image_size).to have_attributes(attributes)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
context 'with too many redirects' do
|
164
|
+
it 'gets format and dimensions' do
|
165
|
+
expect do
|
166
|
+
ImageSize.url("#{file_url}?redirect=6")
|
167
|
+
end.to raise_error(/Too many redirects/)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
context 'not supporting range' do
|
173
|
+
context 'without redirects' do
|
174
|
+
it 'gets format and dimensions' do
|
175
|
+
image_size = ImageSize.url("#{file_url}?ignore_range")
|
176
|
+
expect(image_size).to have_attributes(attributes)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
context 'with redirects' do
|
181
|
+
it 'gets format and dimensions' do
|
182
|
+
image_size = ImageSize.url("#{file_url}?ignore_range&redirect=5")
|
183
|
+
expect(image_size).to have_attributes(attributes)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
context 'with too many redirects' do
|
188
|
+
it 'gets format and dimensions' do
|
189
|
+
expect do
|
190
|
+
ImageSize.url("#{file_url}?ignore_range&redirect=6")
|
191
|
+
end.to raise_error(/Too many redirects/)
|
192
|
+
end
|
193
|
+
end
|
137
194
|
end
|
138
195
|
end
|
139
196
|
end
|
Binary file
|
Binary file
|
data/spec/test_server.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'webrick'
|
4
|
+
|
5
|
+
class TestServer
|
6
|
+
attr_reader :base_url
|
7
|
+
|
8
|
+
def initialize(host = '127.0.0.1')
|
9
|
+
server_options = {
|
10
|
+
:Logger => WEBrick::Log.new(StringIO.new),
|
11
|
+
:AccessLog => [],
|
12
|
+
:BindAddress => host,
|
13
|
+
:Port => 0, # get the next available port
|
14
|
+
:DocumentRoot => '.',
|
15
|
+
:RequestCallback => proc do |req, res|
|
16
|
+
redirect = req.query['redirect'].to_i
|
17
|
+
if redirect > 0
|
18
|
+
res.set_redirect(
|
19
|
+
WEBrick::HTTPStatus::TemporaryRedirect,
|
20
|
+
[
|
21
|
+
req.request_uri.port == @base_url.port ? @second_url : @base_url,
|
22
|
+
req.request_uri.request_uri,
|
23
|
+
"?#{encode_www_form(req.query.merge('redirect' => redirect - 1))}",
|
24
|
+
].inject(:+)
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
req.header.delete('range') if req.query['ignore_range']
|
29
|
+
end,
|
30
|
+
}
|
31
|
+
|
32
|
+
@server = WEBrick::HTTPServer.new(server_options)
|
33
|
+
@server.listen(host, 0) # listen on second port
|
34
|
+
|
35
|
+
@base_url = URI("http://#{host}:#{@server.listeners[0].addr[1]}/")
|
36
|
+
@second_url = URI("http://#{host}:#{@server.listeners[1].addr[1]}/")
|
37
|
+
|
38
|
+
@thread = Thread.new{ @server.start }
|
39
|
+
end
|
40
|
+
|
41
|
+
def finish
|
42
|
+
@server.shutdown
|
43
|
+
@thread.join
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
if URI.respond_to?(:encode_www_form)
|
49
|
+
def encode_www_form(h)
|
50
|
+
URI.encode_www_form(h)
|
51
|
+
end
|
52
|
+
else
|
53
|
+
require 'cgi'
|
54
|
+
|
55
|
+
def encode_www_form(h)
|
56
|
+
h.map do |k, v|
|
57
|
+
"#{CGI.escape(k)}=#{CGI.escape(v.to_s)}"
|
58
|
+
end.join('&')
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: image_size
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0
|
4
|
+
version: 3.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Keisuke Minami
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2022-
|
12
|
+
date: 2022-11-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -53,8 +53,9 @@ dependencies:
|
|
53
53
|
- - "~>"
|
54
54
|
- !ruby/object:Gem::Version
|
55
55
|
version: '2.0'
|
56
|
-
description: 'Measure following file dimensions: apng, bmp, cur, gif, ico, j2c,
|
57
|
-
jpeg, jpx, mng, pam, pbm, pcx, pgm, png, ppm, psd, svg, swf, tiff, webp, xbm,
|
56
|
+
description: 'Measure following file dimensions: apng, bmp, cur, emf, gif, ico, j2c,
|
57
|
+
jp2, jpeg, jpx, mng, pam, pbm, pcx, pgm, png, ppm, psd, svg, swf, tiff, webp, xbm,
|
58
|
+
xpm'
|
58
59
|
email:
|
59
60
|
executables: []
|
60
61
|
extensions: []
|
@@ -86,6 +87,8 @@ files:
|
|
86
87
|
- spec/images/bmp/v3-bottom2top.42x50.bmp
|
87
88
|
- spec/images/bmp/v3-top2bottom.42x50.bmp
|
88
89
|
- spec/images/cur/32x256.cur
|
90
|
+
- spec/images/emf/74x77.emf
|
91
|
+
- spec/images/emf/77x77.emf
|
89
92
|
- spec/images/empty
|
90
93
|
- spec/images/gif/668x481.gif
|
91
94
|
- spec/images/ico/32x256.ico
|
@@ -120,13 +123,14 @@ files:
|
|
120
123
|
- spec/images/xbm/crlf.16x32.xbm
|
121
124
|
- spec/images/xpm/24x32.xpm
|
122
125
|
- spec/images/xpm/crlf.24x32.xpm
|
126
|
+
- spec/test_server.rb
|
123
127
|
homepage: https://github.com/toy/image_size
|
124
128
|
licenses:
|
125
129
|
- Ruby
|
126
130
|
metadata:
|
127
131
|
bug_tracker_uri: https://github.com/toy/image_size/issues
|
128
132
|
changelog_uri: https://github.com/toy/image_size/blob/master/CHANGELOG.markdown
|
129
|
-
documentation_uri: https://www.rubydoc.info/gems/image_size/3.0
|
133
|
+
documentation_uri: https://www.rubydoc.info/gems/image_size/3.2.0
|
130
134
|
source_code_uri: https://github.com/toy/image_size
|
131
135
|
post_install_message:
|
132
136
|
rdoc_options: []
|
@@ -156,6 +160,8 @@ test_files:
|
|
156
160
|
- spec/images/bmp/v3-bottom2top.42x50.bmp
|
157
161
|
- spec/images/bmp/v3-top2bottom.42x50.bmp
|
158
162
|
- spec/images/cur/32x256.cur
|
163
|
+
- spec/images/emf/74x77.emf
|
164
|
+
- spec/images/emf/77x77.emf
|
159
165
|
- spec/images/empty
|
160
166
|
- spec/images/gif/668x481.gif
|
161
167
|
- spec/images/ico/32x256.ico
|
@@ -190,3 +196,4 @@ test_files:
|
|
190
196
|
- spec/images/xbm/crlf.16x32.xbm
|
191
197
|
- spec/images/xpm/24x32.xpm
|
192
198
|
- spec/images/xpm/crlf.24x32.xpm
|
199
|
+
- spec/test_server.rb
|