image_size 1.5.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -13
- data/.rubocop.yml +61 -0
- data/.rubocop_todo.yml +25 -0
- data/.travis.yml +18 -9
- data/CHANGELOG.markdown +104 -0
- data/Gemfile +5 -1
- data/README.markdown +64 -26
- data/image_size.gemspec +4 -1
- data/lib/image_size.rb +49 -61
- data/spec/image_size_spec.rb +71 -51
- metadata +28 -12
checksums.yaml
CHANGED
|
@@ -1,15 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
|
|
5
|
-
data.tar.gz: !binary |-
|
|
6
|
-
N2VmMzkwMWFmNzY5NmM5YTY0NTJmOWU5ZDlkMDBiYTlmYTA0NDY3Yg==
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 82a7fbf13124c2d0472d5da0f7d210ef83519dcde8927ec9db13954cf3f3d44c
|
|
4
|
+
data.tar.gz: 5b77e47649b9632ec16b882397d367343d61750884ab9642170150ec43f9895c
|
|
7
5
|
SHA512:
|
|
8
|
-
metadata.gz:
|
|
9
|
-
|
|
10
|
-
MjNiNjRhZDVlY2FkMDk0Mzk2YjlkZmIwMGM0ZjM4NzUyNjhkOThiYmM2M2Ji
|
|
11
|
-
NzNhZDNlMjVkZjcxYWM2NjgyYjdhNDNhNGVmNzZhOGVlYTdjMDE=
|
|
12
|
-
data.tar.gz: !binary |-
|
|
13
|
-
ZTM0NDI5YmFkOTM3YjAzNWY2OWQ3Y2U0ODBlMDhhYzBiYzYzYWVjMzE0Njg1
|
|
14
|
-
NWI0ZDA4MmZhZDY2ODc1YTExYjIzYWYzZTM2OTFiOTNmNDNhYmJkZjU1ZGRl
|
|
15
|
-
MmZiNDY0NTIyODE1YzZlZGQwODM2MTZlMTA3MThlNGQ4N2I3ODE=
|
|
6
|
+
metadata.gz: f1e666a5911f31b8b3d44cf94ab3223621561026f6701e43e8db39e3d36761641a6f8122cdcd9bff18740a50679ebec593de7b73dd5ea36309d4688f7926f29e
|
|
7
|
+
data.tar.gz: 6322a3aa7488e76f2cd26ef0eb83492269165ba4948a2f888bf935d48ccba86d20f0fb306252ed0dc1af5e5adce11442edb70586331b40070fec866d46ae36e1
|
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
inherit_from: .rubocop_todo.yml
|
|
2
|
+
|
|
3
|
+
AllCops:
|
|
4
|
+
Exclude:
|
|
5
|
+
- '*.gemspec'
|
|
6
|
+
|
|
7
|
+
Layout/AccessModifierIndentation:
|
|
8
|
+
EnforcedStyle: outdent
|
|
9
|
+
|
|
10
|
+
Layout/CaseIndentation:
|
|
11
|
+
EnforcedStyle: end
|
|
12
|
+
|
|
13
|
+
Layout/EndAlignment:
|
|
14
|
+
EnforcedStyleAlignWith: variable
|
|
15
|
+
|
|
16
|
+
Layout/SpaceBeforeBlockBraces:
|
|
17
|
+
EnforcedStyle: no_space
|
|
18
|
+
EnforcedStyleForEmptyBraces: no_space
|
|
19
|
+
|
|
20
|
+
Lint/PercentStringArray: # broken in rubocop 0.55.0
|
|
21
|
+
Enabled: false
|
|
22
|
+
|
|
23
|
+
Metrics/BlockLength:
|
|
24
|
+
Exclude:
|
|
25
|
+
- 'spec/**/*.rb'
|
|
26
|
+
|
|
27
|
+
Metrics/ClassLength:
|
|
28
|
+
Enabled: false
|
|
29
|
+
|
|
30
|
+
Metrics/LineLength:
|
|
31
|
+
Max: 120
|
|
32
|
+
|
|
33
|
+
Metrics/MethodLength:
|
|
34
|
+
Enabled: false
|
|
35
|
+
|
|
36
|
+
Naming/UncommunicativeMethodParamName:
|
|
37
|
+
Enabled: false
|
|
38
|
+
|
|
39
|
+
Style/Alias:
|
|
40
|
+
EnforcedStyle: prefer_alias_method
|
|
41
|
+
|
|
42
|
+
Style/EmptyCaseCondition:
|
|
43
|
+
Enabled: false
|
|
44
|
+
|
|
45
|
+
Style/Encoding:
|
|
46
|
+
Enabled: false
|
|
47
|
+
|
|
48
|
+
Style/HashSyntax:
|
|
49
|
+
EnforcedStyle: hash_rockets
|
|
50
|
+
|
|
51
|
+
Style/IfUnlessModifier:
|
|
52
|
+
Enabled: false
|
|
53
|
+
|
|
54
|
+
Style/ParallelAssignment:
|
|
55
|
+
Enabled: false
|
|
56
|
+
|
|
57
|
+
Style/TrailingCommaInArrayLiteral:
|
|
58
|
+
EnforcedStyleForMultiline: comma
|
|
59
|
+
|
|
60
|
+
Style/TrailingCommaInHashLiteral:
|
|
61
|
+
EnforcedStyleForMultiline: comma
|
data/.rubocop_todo.yml
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# This configuration was generated by
|
|
2
|
+
# `rubocop --auto-gen-config`
|
|
3
|
+
# on 2018-04-23 23:58:18 +0200 using RuboCop version 0.55.0.
|
|
4
|
+
# The point is for the user to remove these configuration records
|
|
5
|
+
# one by one as the offenses are removed from the code base.
|
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
|
8
|
+
|
|
9
|
+
# Offense count: 6
|
|
10
|
+
Metrics/AbcSize:
|
|
11
|
+
Max: 41
|
|
12
|
+
|
|
13
|
+
# Offense count: 3
|
|
14
|
+
Metrics/CyclomaticComplexity:
|
|
15
|
+
Max: 20
|
|
16
|
+
|
|
17
|
+
# Offense count: 2
|
|
18
|
+
Metrics/PerceivedComplexity:
|
|
19
|
+
Max: 20
|
|
20
|
+
|
|
21
|
+
# Offense count: 7
|
|
22
|
+
# Cop supports --auto-correct.
|
|
23
|
+
Style/PerlBackrefs:
|
|
24
|
+
Exclude:
|
|
25
|
+
- 'lib/image_size.rb'
|
data/.travis.yml
CHANGED
|
@@ -3,13 +3,22 @@ language: ruby
|
|
|
3
3
|
before_install:
|
|
4
4
|
- gem update bundler
|
|
5
5
|
rvm:
|
|
6
|
-
- '1.8'
|
|
7
|
-
- '1.9'
|
|
8
|
-
- '2.0'
|
|
9
|
-
- '2.1'
|
|
10
|
-
- '2.2'
|
|
11
|
-
- '2.3.
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
6
|
+
- '1.8.7-p371'
|
|
7
|
+
- '1.9.3-p551'
|
|
8
|
+
- '2.0.0-p648'
|
|
9
|
+
- '2.1.10'
|
|
10
|
+
- '2.2.10'
|
|
11
|
+
- '2.3.7'
|
|
12
|
+
- '2.4.4'
|
|
13
|
+
- '2.5.1'
|
|
14
|
+
- 'jruby-9.0.5.0'
|
|
15
|
+
- 'jruby-9.1.9.0'
|
|
15
16
|
script: bundle exec rspec
|
|
17
|
+
matrix:
|
|
18
|
+
include:
|
|
19
|
+
- env: RUBOCOP=✓
|
|
20
|
+
rvm: '2.4.4'
|
|
21
|
+
script: bundle exec rubocop
|
|
22
|
+
- env: CHECK_RUBIES=✓
|
|
23
|
+
rvm: '2.4.4'
|
|
24
|
+
script: bundle exec travis_check_rubies
|
data/CHANGELOG.markdown
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# ChangeLog
|
|
2
|
+
|
|
3
|
+
## unreleased
|
|
4
|
+
|
|
5
|
+
## v2.0.0 (2018-05-01)
|
|
6
|
+
|
|
7
|
+
* Allow any class responding to `read` and `eof?` to be passed to `ImageSize` [@toy](https://github.com/toy)
|
|
8
|
+
* Introduce `rubocop` [@toy](https://github.com/toy)
|
|
9
|
+
* Use `File.open` instead of `Kernel#open` [@toy](https://github.com/toy)
|
|
10
|
+
* Don’t rewind `IO` before or after usage [@toy](https://github.com/toy)
|
|
11
|
+
* Enhance readme [@toy](https://github.com/toy)
|
|
12
|
+
|
|
13
|
+
## v1.5.0 (2016-11-20)
|
|
14
|
+
|
|
15
|
+
* Support `WEBP` images [@toy](https://github.com/toy)
|
|
16
|
+
* Cleanup `GIF`, `PPM` and `SWF` magic number matching [@toy](https://github.com/toy)
|
|
17
|
+
* Fix `GIF` magic number (matched `GIF8,a`) [@toy](https://github.com/toy)
|
|
18
|
+
* Detect `APNG` images by `acTL` chunk [@toy](https://github.com/toy)
|
|
19
|
+
* Support `MNG` images [@toy](https://github.com/toy)
|
|
20
|
+
|
|
21
|
+
## v1.4.2 (2016-02-18)
|
|
22
|
+
|
|
23
|
+
* Fixed license in gemspec to be Ruby [#10](https://github.com/toy/image_size/issues/10) [@toy](https://github.com/toy)
|
|
24
|
+
|
|
25
|
+
## v1.4.1 (2014-11-19)
|
|
26
|
+
|
|
27
|
+
* Missed `ICO` and `CUR` in description [@toy](https://github.com/toy)
|
|
28
|
+
|
|
29
|
+
## v1.4.0 (2014-11-19)
|
|
30
|
+
|
|
31
|
+
* Detecting `ICO` and `CUR` images [@toy](https://github.com/toy)
|
|
32
|
+
|
|
33
|
+
## v1.3.1 (2014-06-24)
|
|
34
|
+
|
|
35
|
+
* Fix reading `JPEGs` with extraneous bytes [@toy](https://github.com/toy)
|
|
36
|
+
|
|
37
|
+
## v1.3.0 (2014-04-06)
|
|
38
|
+
|
|
39
|
+
* Raise `FormatError` instead of `RuntimeError` [@toy](https://github.com/toy)
|
|
40
|
+
|
|
41
|
+
## v1.2.0 (2014-02-01)
|
|
42
|
+
|
|
43
|
+
* Basic handling of `SVG` (only width and height attributes) [@toy](https://github.com/toy)
|
|
44
|
+
* Enhance matching `PCX` [@toy](https://github.com/toy)
|
|
45
|
+
|
|
46
|
+
## v1.1.5 (2013-12-23)
|
|
47
|
+
|
|
48
|
+
* Fix reading dimensions of `BMP v2` and `BMP v3` [@toy](https://github.com/toy)
|
|
49
|
+
* Fix swapped `PSD` width (columns) and height (rows) [#9](https://github.com/toy/image_size/issues/9) [@toy](https://github.com/toy)
|
|
50
|
+
* Replace square test images with rectangle ones [@toy](https://github.com/toy)
|
|
51
|
+
|
|
52
|
+
## v1.1.4 (2013-11-05)
|
|
53
|
+
|
|
54
|
+
* Close instead of only rewinding `IO` instances [@toy](https://github.com/toy)
|
|
55
|
+
* Add `.travis.yml` and supporting files [#8](https://github.com/toy/image_size/pull/8) [@petergoldstein](https://github.com/petergoldstein)
|
|
56
|
+
|
|
57
|
+
## v1.1.3 (2013-07-24)
|
|
58
|
+
|
|
59
|
+
* Enforce binary encoding of data returned by `ImageReader#[]` [#6](https://github.com/toy/image_size/issues/6) [@toy](https://github.com/toy)
|
|
60
|
+
|
|
61
|
+
## v1.1.2 (2013-02-24)
|
|
62
|
+
|
|
63
|
+
* Explicitly set encoding to `ASCII-8BIT` as for `ruby2.0.0-p0` it will be `UTF-8` by default [#5](https://github.com/toy/image_size/pull/5) [@walf443](https://github.com/walf443)
|
|
64
|
+
|
|
65
|
+
## v1.1.1 (2012-06-19)
|
|
66
|
+
|
|
67
|
+
* Fix exception in message for exception [#3](https://github.com/toy/image_size/pull/3) [@yachi](https://github.com/yachi)
|
|
68
|
+
|
|
69
|
+
## v1.1.0 (2012-02-25)
|
|
70
|
+
|
|
71
|
+
* Rework most code [@toy](https://github.com/toy)
|
|
72
|
+
* `Size` class instead of dynamically adding `to_s` method to size array [@toy](https://github.com/toy)
|
|
73
|
+
* `ImageSize.path`, more examples [@toy](https://github.com/toy)
|
|
74
|
+
* Added support for `Tempfile`, as well as fixed bug when running `ImageSize` on the same `IO` stream twice [#2](https://github.com/toy/image_size/pull/2) [@kanevski](https://github.com/kanevski)
|
|
75
|
+
|
|
76
|
+
## v1.0.6 (2012-02-08)
|
|
77
|
+
|
|
78
|
+
* Internal gem changes [@toy](https://github.com/toy)
|
|
79
|
+
|
|
80
|
+
## v1.0.5 (2012-02-04)
|
|
81
|
+
|
|
82
|
+
* Fix getting `SWF` dimensions for ruby 1.9 [@toy](https://github.com/toy)
|
|
83
|
+
* Fix determining `PCX` for ruby1.9 [@toy](https://github.com/toy)
|
|
84
|
+
* Enhance `SWF` checking [@toy](https://github.com/toy)
|
|
85
|
+
|
|
86
|
+
## v1.0.4 (2011-12-16)
|
|
87
|
+
|
|
88
|
+
* Internal gem changes [@toy](https://github.com/toy)
|
|
89
|
+
|
|
90
|
+
## v1.0.3 (2011-02-21)
|
|
91
|
+
|
|
92
|
+
* Fix permissions on `lib/image_size.rb` from `700` to `644` [#1](https://github.com/toy/image_size/issues/1) [@toy](https://github.com/toy)
|
|
93
|
+
|
|
94
|
+
## v1.0.2 (2010-12-15)
|
|
95
|
+
|
|
96
|
+
* Internal gem changes [@toy](https://github.com/toy)
|
|
97
|
+
|
|
98
|
+
## v1.0.1 (2010-12-15)
|
|
99
|
+
|
|
100
|
+
* Internal gem changes [@toy](https://github.com/toy)
|
|
101
|
+
|
|
102
|
+
## v1.0.0 (2010-11-01)
|
|
103
|
+
|
|
104
|
+
* Initial commit [@toy](https://github.com/toy)
|
data/Gemfile
CHANGED
data/README.markdown
CHANGED
|
@@ -1,50 +1,87 @@
|
|
|
1
|
+
[](https://rubygems.org/gems/image_size)
|
|
2
|
+
[](https://travis-ci.org/toy/image_size)
|
|
3
|
+
|
|
1
4
|
# image_size
|
|
2
5
|
|
|
3
6
|
measure image size using pure Ruby
|
|
4
7
|
formats: `apng`, `bmp`, `cur`, `gif`, `jpeg`, `ico`, `mng`, `pbm`, `pcx`, `pgm`, `png`, `ppm`, `psd`, `swf`, `tiff`, `xbm`, `xpm`, `webp`
|
|
5
8
|
|
|
6
|
-
|
|
9
|
+
## Installation
|
|
7
10
|
|
|
8
|
-
|
|
11
|
+
```sh
|
|
12
|
+
gem install image_size
|
|
13
|
+
```
|
|
9
14
|
|
|
10
|
-
|
|
15
|
+
### Bundler
|
|
11
16
|
|
|
12
|
-
|
|
17
|
+
Add to your `Gemfile`:
|
|
13
18
|
|
|
14
|
-
|
|
19
|
+
```ruby
|
|
20
|
+
gem 'image_size', '~> 2.0'
|
|
21
|
+
```
|
|
15
22
|
|
|
16
23
|
## Usage
|
|
17
24
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
25
|
+
```ruby
|
|
26
|
+
image_size = ImageSize.path('spec/test.jpg')
|
|
27
|
+
|
|
28
|
+
image_size.format #=> :jpec
|
|
29
|
+
image_size.width #=> 320
|
|
30
|
+
image_size.height #=> 240
|
|
31
|
+
image_size.w #=> 320
|
|
32
|
+
image_size.h #=> 240
|
|
33
|
+
image_size.size #=> [320, 240]
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Or using `IO` object:
|
|
37
|
+
|
|
38
|
+
```ruby
|
|
39
|
+
image_size = File.open('spec/test.jpg', 'rb'){ |fh| ImageSize.new(fh) }
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Any object responding to `read` and `eof?`:
|
|
43
|
+
|
|
44
|
+
```ruby
|
|
45
|
+
require 'image_size'
|
|
46
|
+
|
|
47
|
+
image_size = ImageSize.new(ARGF)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Works with `open-uri` if needed:
|
|
23
51
|
|
|
24
|
-
|
|
52
|
+
```ruby
|
|
53
|
+
require 'image_size'
|
|
54
|
+
require 'open-uri'
|
|
25
55
|
|
|
26
|
-
|
|
56
|
+
image_size = URI.parse('http://www.rubycgi.org/image/ruby_gtk_book_title.jpg').open('rb') do |fh|
|
|
57
|
+
ImageSize.new(fh)
|
|
58
|
+
end
|
|
27
59
|
|
|
28
|
-
|
|
60
|
+
image_size = open('http://www.rubycgi.org/image/ruby_gtk_book_title.jpg', 'rb') do |fh|
|
|
61
|
+
ImageSize.new(fh)
|
|
62
|
+
end
|
|
63
|
+
```
|
|
29
64
|
|
|
30
|
-
|
|
65
|
+
Note that starting with version `2.0.0` the object given to `ImageSize` will not be rewound before or after use.
|
|
66
|
+
So rewind if needed before passing to `ImageSize` and/or rewind after passing to `ImageSize` before reading data.
|
|
31
67
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
end
|
|
68
|
+
```ruby
|
|
69
|
+
require 'image_size'
|
|
35
70
|
|
|
71
|
+
File.open('spec/test.jpg', 'rb') do |fh|
|
|
72
|
+
image_size = ImageSize.new(fh)
|
|
36
73
|
|
|
37
|
-
|
|
38
|
-
|
|
74
|
+
fh.rewind
|
|
75
|
+
data = fh.read
|
|
76
|
+
end
|
|
39
77
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
78
|
+
File.open('spec/test.jpg', 'rb') do |fh|
|
|
79
|
+
data = fh.read
|
|
80
|
+
fh.rewind
|
|
43
81
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
end
|
|
82
|
+
image_size = ImageSize.new(fh)
|
|
83
|
+
end
|
|
84
|
+
```
|
|
48
85
|
|
|
49
86
|
## Licence
|
|
50
87
|
|
|
@@ -53,3 +90,4 @@ This code is free to use under the terms of the Ruby's licence.
|
|
|
53
90
|
## Contact
|
|
54
91
|
|
|
55
92
|
Original author: "Keisuke Minami": mailto:keisuke@rccn.com
|
|
93
|
+
Further development by Ivan Kuchin https://github.com/toy/image_size
|
data/image_size.gemspec
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Gem::Specification.new do |s|
|
|
4
4
|
s.name = 'image_size'
|
|
5
|
-
s.version = '
|
|
5
|
+
s.version = '2.0.0'
|
|
6
6
|
s.summary = %q{Measure image size using pure Ruby}
|
|
7
7
|
s.description = %q{Measure following file dimensions: apng, bmp, cur, gif, jpeg, ico, mng, pbm, pcx, pgm, png, ppm, psd, swf, tiff, xbm, xpm, webp}
|
|
8
8
|
s.homepage = "http://github.com/toy/#{s.name}"
|
|
@@ -17,4 +17,7 @@ Gem::Specification.new do |s|
|
|
|
17
17
|
s.require_paths = %w[lib]
|
|
18
18
|
|
|
19
19
|
s.add_development_dependency 'rspec', '~> 3.0'
|
|
20
|
+
if RUBY_VERSION >= '2.1'
|
|
21
|
+
s.add_development_dependency 'rubocop', '~> 0.55'
|
|
22
|
+
end
|
|
20
23
|
end
|
data/lib/image_size.rb
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
1
|
+
# encoding: BINARY
|
|
2
|
+
|
|
3
3
|
require 'stringio'
|
|
4
|
-
require 'tempfile'
|
|
5
4
|
|
|
5
|
+
# Determine image format and size
|
|
6
6
|
class ImageSize
|
|
7
7
|
class FormatError < StandardError; end
|
|
8
8
|
|
|
9
|
+
# Array joining with 'x'
|
|
9
10
|
class Size < Array
|
|
10
11
|
# join using 'x'
|
|
11
12
|
def to_s
|
|
@@ -16,33 +17,23 @@ class ImageSize
|
|
|
16
17
|
class ImageReader # :nodoc:
|
|
17
18
|
attr_reader :data
|
|
18
19
|
def initialize(data_or_io)
|
|
19
|
-
@io =
|
|
20
|
-
when IO, StringIO, Tempfile
|
|
21
|
-
data_or_io.dup.tap(&:rewind)
|
|
22
|
-
when String
|
|
20
|
+
@io = if data_or_io.is_a?(String)
|
|
23
21
|
StringIO.new(data_or_io)
|
|
22
|
+
elsif data_or_io.respond_to?(:read) && data_or_io.respond_to?(:eof?)
|
|
23
|
+
data_or_io
|
|
24
24
|
else
|
|
25
|
-
raise ArgumentError
|
|
25
|
+
raise ArgumentError, "expected data as String or an object responding to read and eof?, got #{data_or_io.class}"
|
|
26
26
|
end
|
|
27
|
-
@read = 0
|
|
28
27
|
@data = ''
|
|
29
28
|
end
|
|
30
29
|
|
|
31
|
-
def close
|
|
32
|
-
@io.rewind
|
|
33
|
-
@io.close if IO === @io
|
|
34
|
-
end
|
|
35
|
-
|
|
36
30
|
CHUNK = 1024
|
|
37
31
|
def [](offset, length)
|
|
38
|
-
while offset + length
|
|
39
|
-
@read
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
end
|
|
44
|
-
@data << data
|
|
45
|
-
end
|
|
32
|
+
while !@io.eof? && @data.length < offset + length
|
|
33
|
+
data = @io.read(CHUNK)
|
|
34
|
+
break unless data
|
|
35
|
+
data.force_encoding(@data.encoding) if data.respond_to?(:encoding)
|
|
36
|
+
@data << data
|
|
46
37
|
end
|
|
47
38
|
@data[offset, length]
|
|
48
39
|
end
|
|
@@ -50,7 +41,7 @@ class ImageSize
|
|
|
50
41
|
|
|
51
42
|
# Given path to image finds its format, width and height
|
|
52
43
|
def self.path(path)
|
|
53
|
-
open(path, 'rb'){ |f| new(f) }
|
|
44
|
+
File.open(path, 'rb'){ |f| new(f) }
|
|
54
45
|
end
|
|
55
46
|
|
|
56
47
|
# Used for svg
|
|
@@ -63,13 +54,12 @@ class ImageSize
|
|
|
63
54
|
@dpi = dpi.to_f
|
|
64
55
|
end
|
|
65
56
|
|
|
66
|
-
# Given image as
|
|
57
|
+
# Given image as any class responding to read and eof? or data as String, finds its format and dimensions
|
|
67
58
|
def initialize(data)
|
|
68
59
|
ir = ImageReader.new(data)
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
ir.close
|
|
60
|
+
@format = detect_format(ir)
|
|
61
|
+
return unless @format
|
|
62
|
+
@width, @height = send("size_of_#{@format}", ir)
|
|
73
63
|
end
|
|
74
64
|
|
|
75
65
|
# Image format
|
|
@@ -77,11 +67,11 @@ class ImageSize
|
|
|
77
67
|
|
|
78
68
|
# Image width
|
|
79
69
|
attr_reader :width
|
|
80
|
-
|
|
70
|
+
alias_method :w, :width
|
|
81
71
|
|
|
82
72
|
# Image height
|
|
83
73
|
attr_reader :height
|
|
84
|
-
|
|
74
|
+
alias_method :h, :height
|
|
85
75
|
|
|
86
76
|
# get image width and height as an array which to_s method returns "#{width}x#{height}"
|
|
87
77
|
def size
|
|
@@ -103,7 +93,7 @@ private
|
|
|
103
93
|
when head =~ /\#define\s+\S+\s+\d+/ then :xbm
|
|
104
94
|
when head[0, 4] == "II*\000" then :tiff
|
|
105
95
|
when head[0, 4] == "MM\000*" then :tiff
|
|
106
|
-
when head =~
|
|
96
|
+
when head =~ %r{/\* XPM \*/} then :xpm
|
|
107
97
|
when head[0, 4] == '8BPS' then :psd
|
|
108
98
|
when head[0, 3] =~ /[FC]WS/ then :swf
|
|
109
99
|
when head[SVG_R] ||
|
|
@@ -148,12 +138,12 @@ private
|
|
|
148
138
|
end
|
|
149
139
|
alias_method :size_of_apng, :size_of_png
|
|
150
140
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
]
|
|
141
|
+
JPEG_CODE_CHECK = %W[
|
|
142
|
+
\xC0 \xC1 \xC2 \xC3
|
|
143
|
+
\xC5 \xC6 \xC7
|
|
144
|
+
\xC9 \xCA \xCB
|
|
145
|
+
\xCD \xCE \xCF
|
|
146
|
+
].freeze
|
|
157
147
|
def size_of_jpeg(ir)
|
|
158
148
|
section_marker = "\xFF"
|
|
159
149
|
offset = 2
|
|
@@ -162,10 +152,10 @@ private
|
|
|
162
152
|
offset += 1 until section_marker != ir[offset + 1, 1]
|
|
163
153
|
raise FormatError, 'EOF in JPEG' if ir[offset, 1].nil?
|
|
164
154
|
|
|
165
|
-
|
|
155
|
+
_marker, code, length = ir[offset, 4].unpack('aan')
|
|
166
156
|
offset += 4
|
|
167
157
|
|
|
168
|
-
if
|
|
158
|
+
if JPEG_CODE_CHECK.include?(code)
|
|
169
159
|
return ir[offset + 1, 4].unpack('nn').reverse
|
|
170
160
|
end
|
|
171
161
|
offset += length - 2
|
|
@@ -192,8 +182,8 @@ private
|
|
|
192
182
|
header.gsub!(/^\#[^\n\r]*/m, '')
|
|
193
183
|
header =~ /^(P[1-6])\s+?(\d+)\s+?(\d+)/m
|
|
194
184
|
case $1
|
|
195
|
-
|
|
196
|
-
|
|
185
|
+
when 'P1', 'P4' then @format = :pbm
|
|
186
|
+
when 'P2', 'P5' then @format = :pgm
|
|
197
187
|
end
|
|
198
188
|
[$2.to_i, $3.to_i]
|
|
199
189
|
end
|
|
@@ -219,7 +209,7 @@ private
|
|
|
219
209
|
end
|
|
220
210
|
|
|
221
211
|
def size_of_tiff(ir)
|
|
222
|
-
endian2b =
|
|
212
|
+
endian2b = ir[0, 4] == "II*\000" ? 'v' : 'n'
|
|
223
213
|
endian4b = endian2b.upcase
|
|
224
214
|
packspec = [nil, 'C', nil, endian2b, endian4b, nil, 'c', nil, endian2b, endian4b]
|
|
225
215
|
|
|
@@ -235,14 +225,13 @@ private
|
|
|
235
225
|
tag, type = ifd.unpack(endian2b * 2)
|
|
236
226
|
offset += 12
|
|
237
227
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
end
|
|
228
|
+
next if packspec[type].nil?
|
|
229
|
+
value = ifd[8, 4].unpack(packspec[type])[0]
|
|
230
|
+
case tag
|
|
231
|
+
when 0x0100
|
|
232
|
+
width = value
|
|
233
|
+
when 0x0101
|
|
234
|
+
height = value
|
|
246
235
|
end
|
|
247
236
|
end
|
|
248
237
|
[width, height]
|
|
@@ -269,18 +258,17 @@ private
|
|
|
269
258
|
end
|
|
270
259
|
dpi = self.class.dpi
|
|
271
260
|
[attributes['width'], attributes['height']].map do |length|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
end
|
|
282
|
-
pixels.round if pixels
|
|
261
|
+
next unless length
|
|
262
|
+
pixels = case length.downcase.strip[/(?:em|ex|px|in|cm|mm|pt|pc|%)\z/]
|
|
263
|
+
when 'em', 'ex', '%' then nil
|
|
264
|
+
when 'in' then length.to_f * dpi
|
|
265
|
+
when 'cm' then length.to_f * dpi / 2.54
|
|
266
|
+
when 'mm' then length.to_f * dpi / 25.4
|
|
267
|
+
when 'pt' then length.to_f * dpi / 72
|
|
268
|
+
when 'pc' then length.to_f * dpi / 6
|
|
269
|
+
else length.to_f
|
|
283
270
|
end
|
|
271
|
+
pixels.round if pixels
|
|
284
272
|
end
|
|
285
273
|
end
|
|
286
274
|
|
data/spec/image_size_spec.rb
CHANGED
|
@@ -1,69 +1,89 @@
|
|
|
1
1
|
require 'rspec'
|
|
2
2
|
require 'image_size'
|
|
3
|
+
require 'tempfile'
|
|
3
4
|
|
|
4
5
|
describe ImageSize do
|
|
5
6
|
(Dir['spec/images/*/*.*'] + [__FILE__]).each do |path|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
7
|
+
describe "for #{path}" do
|
|
8
|
+
let(:name){ File.basename(path) }
|
|
9
|
+
let(:attributes) do
|
|
10
|
+
match = /(\d+)x(\d+)\.([^.]+)$/.match(name)
|
|
11
|
+
width, height, format = match[1].to_i, match[2].to_i, match[3].to_sym if match
|
|
12
|
+
size = format && [width, height]
|
|
13
|
+
{
|
|
14
|
+
:format => format,
|
|
15
|
+
:width => width,
|
|
16
|
+
:height => height,
|
|
17
|
+
:w => width,
|
|
18
|
+
:h => height,
|
|
19
|
+
:size => size,
|
|
20
|
+
}
|
|
18
21
|
end
|
|
19
|
-
|
|
22
|
+
let(:file_data){ File.open(path, 'rb', &:read) }
|
|
20
23
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
context 'given as data' do
|
|
25
|
+
it 'gets format and dimensions' do
|
|
26
|
+
data = file_data.dup
|
|
27
|
+
image_size = ImageSize.new(data)
|
|
28
|
+
expect(image_size).to have_attributes(attributes)
|
|
29
|
+
expect(data).to eq(file_data)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
29
32
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
context 'given as IO' do
|
|
34
|
+
it 'gets format and dimensions' do
|
|
35
|
+
File.open(path, 'rb') do |io|
|
|
36
|
+
image_size = ImageSize.new(io)
|
|
37
|
+
expect(image_size).to have_attributes(attributes)
|
|
38
|
+
expect(io).not_to be_closed
|
|
39
|
+
expect(io.pos).to_not be_zero
|
|
40
|
+
io.rewind
|
|
41
|
+
expect(io.read).to eq(file_data)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
34
45
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
context 'given as StringIO' do
|
|
47
|
+
it 'gets format and dimensions' do
|
|
48
|
+
io = StringIO.new(file_data)
|
|
49
|
+
image_size = ImageSize.new(io)
|
|
50
|
+
expect(image_size).to have_attributes(attributes)
|
|
51
|
+
expect(io).not_to be_closed
|
|
52
|
+
expect(io.pos).to_not be_zero
|
|
53
|
+
io.rewind
|
|
54
|
+
expect(io.read).to eq(file_data)
|
|
55
|
+
end
|
|
45
56
|
end
|
|
46
|
-
end
|
|
47
57
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
58
|
+
context 'given as Tempfile' do
|
|
59
|
+
it 'gets format and dimensions' do
|
|
60
|
+
Tempfile.open(name) do |io|
|
|
61
|
+
io.binmode
|
|
62
|
+
io.write(file_data)
|
|
63
|
+
io.rewind
|
|
64
|
+
image_size = ImageSize.new(io)
|
|
65
|
+
expect(image_size).to have_attributes(attributes)
|
|
66
|
+
expect(io).not_to be_closed
|
|
67
|
+
expect(io.pos).to_not be_zero
|
|
68
|
+
io.rewind
|
|
69
|
+
expect(io.read).to eq(file_data)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
54
72
|
end
|
|
55
|
-
end
|
|
56
73
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
74
|
+
context 'using path method' do
|
|
75
|
+
it 'gets format and dimensions' do
|
|
76
|
+
image_size = ImageSize.path(path)
|
|
77
|
+
expect(image_size).to have_attributes(attributes)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
60
80
|
end
|
|
61
81
|
end
|
|
62
82
|
|
|
63
|
-
it
|
|
64
|
-
expect
|
|
83
|
+
it 'raises ArgumentError if argument is not valid' do
|
|
84
|
+
expect do
|
|
65
85
|
ImageSize.new(Object)
|
|
66
|
-
|
|
86
|
+
end.to raise_error(ArgumentError)
|
|
67
87
|
end
|
|
68
88
|
|
|
69
89
|
{
|
|
@@ -71,9 +91,9 @@ describe ImageSize do
|
|
|
71
91
|
:jpeg => "\377\330",
|
|
72
92
|
}.each do |type, data|
|
|
73
93
|
it "raises FormatError if invalid #{type} given" do
|
|
74
|
-
expect
|
|
94
|
+
expect do
|
|
75
95
|
ImageSize.new(data)
|
|
76
|
-
|
|
96
|
+
end.to raise_error(ImageSize::FormatError)
|
|
77
97
|
end
|
|
78
98
|
end
|
|
79
99
|
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:
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Keisuke Minami
|
|
@@ -9,31 +9,48 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
12
|
+
date: 2018-05-01 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: rspec
|
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
|
17
17
|
requirements:
|
|
18
|
-
- - ~>
|
|
18
|
+
- - "~>"
|
|
19
19
|
- !ruby/object:Gem::Version
|
|
20
20
|
version: '3.0'
|
|
21
21
|
type: :development
|
|
22
22
|
prerelease: false
|
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
|
24
24
|
requirements:
|
|
25
|
-
- - ~>
|
|
25
|
+
- - "~>"
|
|
26
26
|
- !ruby/object:Gem::Version
|
|
27
27
|
version: '3.0'
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
- !ruby/object:Gem::Dependency
|
|
29
|
+
name: rubocop
|
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
|
31
|
+
requirements:
|
|
32
|
+
- - "~>"
|
|
33
|
+
- !ruby/object:Gem::Version
|
|
34
|
+
version: '0.55'
|
|
35
|
+
type: :development
|
|
36
|
+
prerelease: false
|
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
38
|
+
requirements:
|
|
39
|
+
- - "~>"
|
|
40
|
+
- !ruby/object:Gem::Version
|
|
41
|
+
version: '0.55'
|
|
42
|
+
description: 'Measure following file dimensions: apng, bmp, cur, gif, jpeg, ico, mng,
|
|
43
|
+
pbm, pcx, pgm, png, ppm, psd, swf, tiff, xbm, xpm, webp'
|
|
30
44
|
email:
|
|
31
45
|
executables: []
|
|
32
46
|
extensions: []
|
|
33
47
|
extra_rdoc_files: []
|
|
34
48
|
files:
|
|
35
|
-
- .gitignore
|
|
36
|
-
- .
|
|
49
|
+
- ".gitignore"
|
|
50
|
+
- ".rubocop.yml"
|
|
51
|
+
- ".rubocop_todo.yml"
|
|
52
|
+
- ".travis.yml"
|
|
53
|
+
- CHANGELOG.markdown
|
|
37
54
|
- Gemfile
|
|
38
55
|
- README.markdown
|
|
39
56
|
- image_size.gemspec
|
|
@@ -72,17 +89,17 @@ require_paths:
|
|
|
72
89
|
- lib
|
|
73
90
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
74
91
|
requirements:
|
|
75
|
-
- -
|
|
92
|
+
- - ">="
|
|
76
93
|
- !ruby/object:Gem::Version
|
|
77
94
|
version: '0'
|
|
78
95
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
79
96
|
requirements:
|
|
80
|
-
- -
|
|
97
|
+
- - ">="
|
|
81
98
|
- !ruby/object:Gem::Version
|
|
82
99
|
version: '0'
|
|
83
100
|
requirements: []
|
|
84
101
|
rubyforge_project: image_size
|
|
85
|
-
rubygems_version: 2.6
|
|
102
|
+
rubygems_version: 2.7.6
|
|
86
103
|
signing_key:
|
|
87
104
|
specification_version: 4
|
|
88
105
|
summary: Measure image size using pure Ruby
|
|
@@ -111,4 +128,3 @@ test_files:
|
|
|
111
128
|
- spec/images/webp/lossy.16x32.webp
|
|
112
129
|
- spec/images/xbm/16x32.xbm
|
|
113
130
|
- spec/images/xpm/24x32.xpm
|
|
114
|
-
has_rdoc:
|