image_size 1.5.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Gem Version](https://img.shields.io/gem/v/image_size.svg?style=flat)](https://rubygems.org/gems/image_size)
|
2
|
+
[![Build Status](https://img.shields.io/travis/toy/image_size/master.svg?style=flat)](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:
|