giftrim 0.0.1
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 +15 -0
- data/.gitignore +21 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/LICENSE_MiniMagick.txt +20 -0
- data/README.md +43 -0
- data/Rakefile +1 -0
- data/giftrim.gemspec +28 -0
- data/lib/core_ext/array.rb +7 -0
- data/lib/giftrim/version.rb +3 -0
- data/lib/giftrim.rb +190 -0
- data/test/gifs/0.gif +0 -0
- data/test/giftrim_test.rb +40 -0
- data/test/test_helper.rb +5 -0
- metadata +130 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
!binary "U0hBMQ==":
|
|
3
|
+
metadata.gz: !binary |-
|
|
4
|
+
YzFkZDExNDVjYTA0YTFlYzYxZGNmZGJiODIwYWRjYjBkYTJhMjcwMg==
|
|
5
|
+
data.tar.gz: !binary |-
|
|
6
|
+
YzNmYTA0NGU5ZTVkNTY1N2ZjYmVjY2IwZWI5NjQ4NThhYTU1MWRjMQ==
|
|
7
|
+
!binary "U0hBNTEy":
|
|
8
|
+
metadata.gz: !binary |-
|
|
9
|
+
NWYwNzAyYjc1ZWEyZTcyYTNmMDZkM2Q0ZTlkYzcwYTNkNGM3NGYyMGMwNDQx
|
|
10
|
+
ZDk1ODE2NjZkZDY4MzQxM2JmYmE1MmQ4MWU2ZjY5N2NlZTEwNTk4NWZjYjc5
|
|
11
|
+
ZjVmMTk4MTY4MjRkOTg2MjY4NzY5Mjk4YTQ4NGMzYjIwNDA4M2I=
|
|
12
|
+
data.tar.gz: !binary |-
|
|
13
|
+
N2EyMTRhZmU4YTQxOTU4M2QyZWI4MDk2YzgwZTIzZWU0MDkyZGM1ZWNkY2Qw
|
|
14
|
+
MDJkNjA1ZjllYzljMTkyYTgwZmZjZTVjNjFkMzk1MWI1MjI1Y2I1OWUzNmQ0
|
|
15
|
+
NTYwMjBkZDQ1YzMyMDQ4YjBkMmYzNTMwYmJiYjJjMDFmM2U3M2I=
|
data/.gitignore
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
*.gem
|
|
2
|
+
*.rbc
|
|
3
|
+
.bundle
|
|
4
|
+
.config
|
|
5
|
+
.yardoc
|
|
6
|
+
Gemfile.lock
|
|
7
|
+
InstalledFiles
|
|
8
|
+
_yardoc
|
|
9
|
+
coverage
|
|
10
|
+
doc/
|
|
11
|
+
lib/bundler/man
|
|
12
|
+
pkg
|
|
13
|
+
rdoc
|
|
14
|
+
spec/reports
|
|
15
|
+
test/tmp
|
|
16
|
+
test/version_tmp
|
|
17
|
+
tmp
|
|
18
|
+
test/gifs/*.gif
|
|
19
|
+
test/gifs/output/*.gif
|
|
20
|
+
test/gifs/error/*.gif
|
|
21
|
+
coverage
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2013 Leo Lou
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2005-2013 Corey Johnson probablycorey@gmail.com
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Giftrim
|
|
2
|
+
|
|
3
|
+
Provide convenient methods for GIF optimizations using gifsicle
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Add this line to your application's Gemfile:
|
|
8
|
+
|
|
9
|
+
gem "giftrim"
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### Resize to 300x300, and trim to 10 frames
|
|
14
|
+
```
|
|
15
|
+
image = Giftrim::Image.open "input.gif"
|
|
16
|
+
image.trim
|
|
17
|
+
image.write "output.gif"
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Contributing
|
|
21
|
+
|
|
22
|
+
1. Fork it
|
|
23
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
24
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
25
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
|
26
|
+
5. Create new Pull Request
|
|
27
|
+
|
|
28
|
+
## License
|
|
29
|
+
|
|
30
|
+
See LICENSE.txt and LICENSE_MiniMagick.txt
|
|
31
|
+
|
|
32
|
+
The Testing GIF was retrieved from
|
|
33
|
+
http://commons.wikimedia.org/wiki/File:Lightnings_sequence_2_animation.gif
|
|
34
|
+
licensed under [Creative Commons Attribution-Share Alike 2.5 Generic](http://creativecommons.org/licenses/by-sa/2.5/deed.en) license
|
|
35
|
+
|
|
36
|
+
## Alternatives
|
|
37
|
+
|
|
38
|
+
The first version was at the branch *minimagick*. It adds frames trimming
|
|
39
|
+
methods to MiniMagick::Image. However, from my tests mogrify is not accepting
|
|
40
|
+
`-delete ranges`, such as `-delete 1-2,4,6`.
|
|
41
|
+
|
|
42
|
+
This version uses gifsicle instead of ImageMagick which allows selecting frames
|
|
43
|
+
to be included.
|
data/Rakefile
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require "bundler/gem_tasks"
|
data/giftrim.gemspec
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'giftrim/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "giftrim"
|
|
8
|
+
spec.version = Giftrim::VERSION
|
|
9
|
+
spec.authors = ["Leo Lou"]
|
|
10
|
+
spec.email = ["louyuhong@gmail.com"]
|
|
11
|
+
spec.description = "GIF optimizations using gifsicle"
|
|
12
|
+
spec.summary = "GIF optimizations using gifsicle "
|
|
13
|
+
spec.homepage = "https://github.com/l4u/giftrim"
|
|
14
|
+
spec.license = "MIT"
|
|
15
|
+
|
|
16
|
+
spec.files = `git ls-files`.split($/)
|
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
19
|
+
spec.require_paths = ["lib"]
|
|
20
|
+
|
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
|
22
|
+
spec.add_development_dependency "rake"
|
|
23
|
+
spec.add_development_dependency("simplecov", "~> 0.7")
|
|
24
|
+
spec.add_development_dependency("simplecov-gem-adapter", "~> 1.0.1")
|
|
25
|
+
spec.add_runtime_dependency("subexec", ["~> 0.2.2"])
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
end
|
data/lib/giftrim.rb
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
require 'tempfile'
|
|
2
|
+
require 'subexec'
|
|
3
|
+
require 'stringio'
|
|
4
|
+
require 'pathname'
|
|
5
|
+
require_relative "giftrim/version"
|
|
6
|
+
require_relative "core_ext/array"
|
|
7
|
+
module Giftrim
|
|
8
|
+
class << self
|
|
9
|
+
attr_accessor :timeout
|
|
10
|
+
|
|
11
|
+
def frame_number_wanted total_number, target_number
|
|
12
|
+
(0..(total_number-2)).to_a.spread(target_number)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
class Image
|
|
17
|
+
# @return [String] The location of the current working file
|
|
18
|
+
attr_accessor :path
|
|
19
|
+
|
|
20
|
+
class << self
|
|
21
|
+
|
|
22
|
+
# Modified from MiniMagick, see License_MiniMagick
|
|
23
|
+
# This is the primary loading method used by all of the other class methods.
|
|
24
|
+
#
|
|
25
|
+
# Use this to pass in a stream object. Must respond to Object#read(size) or be a binary string object (BLOBBBB)
|
|
26
|
+
#
|
|
27
|
+
# As a change from the old API, please try and use IOStream objects. They are much, much better and more efficient!
|
|
28
|
+
#
|
|
29
|
+
# Probably easier to use the #open method if you want to open a file or a URL.
|
|
30
|
+
#
|
|
31
|
+
# @param stream [IOStream, String] Some kind of stream object that needs to be read or is a binary String blob!
|
|
32
|
+
# @param ext [String] A manual extension to use for reading the file. Not required, but if you are having issues, give this a try.
|
|
33
|
+
# @return [Image]
|
|
34
|
+
def read(stream, ext = nil)
|
|
35
|
+
if stream.is_a?(String)
|
|
36
|
+
stream = StringIO.new(stream)
|
|
37
|
+
elsif stream.is_a?(StringIO)
|
|
38
|
+
# Do nothing, we want a StringIO-object
|
|
39
|
+
elsif stream.respond_to? :path
|
|
40
|
+
if File.respond_to?(:binread)
|
|
41
|
+
stream = StringIO.new File.binread(stream.path.to_s)
|
|
42
|
+
else
|
|
43
|
+
stream = StringIO.new File.open(stream.path.to_s,"rb") { |f| f.read }
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
create(ext) do |f|
|
|
48
|
+
while chunk = stream.read(8192)
|
|
49
|
+
f.write(chunk)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Modified from MiniMagick, see License_MiniMagick
|
|
55
|
+
# Opens a specific image file either on the local file system or at a URI.
|
|
56
|
+
#
|
|
57
|
+
# Use this if you don't want to overwrite the image file.
|
|
58
|
+
#
|
|
59
|
+
# Extension is either guessed from the path or you can specify it as a second parameter.
|
|
60
|
+
#
|
|
61
|
+
# If you pass in what looks like a URL, we require 'open-uri' before opening it.
|
|
62
|
+
#
|
|
63
|
+
# @param file_or_url [String] Either a local file path or a URL that open-uri can read
|
|
64
|
+
# @param ext [String] Specify the extension you want to read it as
|
|
65
|
+
# @return [Image] The loaded image
|
|
66
|
+
def open(file_or_url, ext = nil)
|
|
67
|
+
file_or_url = file_or_url.to_s # Force it to be a String... hell or highwater
|
|
68
|
+
if file_or_url.include?("://")
|
|
69
|
+
require 'open-uri'
|
|
70
|
+
ext ||= File.extname(URI.parse(file_or_url).path)
|
|
71
|
+
self.read(Kernel::open(file_or_url), ext)
|
|
72
|
+
else
|
|
73
|
+
ext ||= File.extname(file_or_url)
|
|
74
|
+
File.open(file_or_url, "rb") do |f|
|
|
75
|
+
self.read(f, ext)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Modified from MiniMagick, see License_MiniMagick
|
|
81
|
+
# Used to create a new Image object data-copy. Not used to "paint" or that kind of thing.
|
|
82
|
+
#
|
|
83
|
+
# Takes an extension in a block and can be used to build a new Image object. Used
|
|
84
|
+
# by both #open and #read to create a new object! Ensures we have a good tempfile!
|
|
85
|
+
#
|
|
86
|
+
# @param ext [String] Specify the extension you want to read it as
|
|
87
|
+
# @param validate [Boolean] If false, skips validation of the created image. Defaults to true.
|
|
88
|
+
# @yield [IOStream] You can #write bits to this object to create the new Image
|
|
89
|
+
# @return [Image] The created image
|
|
90
|
+
def create(ext = nil, validate = true, &block)
|
|
91
|
+
begin
|
|
92
|
+
tempfile = Tempfile.new(['giftrim_', ext.to_s.downcase])
|
|
93
|
+
tempfile.binmode
|
|
94
|
+
block.call(tempfile)
|
|
95
|
+
tempfile.close
|
|
96
|
+
|
|
97
|
+
image = self.new(tempfile.path, tempfile)
|
|
98
|
+
|
|
99
|
+
if validate and !image.valid?
|
|
100
|
+
raise Giftrim::Invalid
|
|
101
|
+
end
|
|
102
|
+
return image
|
|
103
|
+
ensure
|
|
104
|
+
tempfile.close if tempfile
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Modified from MiniMagick, see License_MiniMagick
|
|
111
|
+
# Create a new MiniMagick::Image object
|
|
112
|
+
#
|
|
113
|
+
# _DANGER_: The file location passed in here is the *working copy*. That is, it gets *modified*.
|
|
114
|
+
# you can either copy it yourself or use the MiniMagick::Image.open(path) method which creates a
|
|
115
|
+
# temporary file for you and protects your original!
|
|
116
|
+
#
|
|
117
|
+
# @param input_path [String] The location of an image file
|
|
118
|
+
# @todo Allow this to accept a block that can pass off to Image#combine_options
|
|
119
|
+
def initialize(input_path, tempfile = nil)
|
|
120
|
+
@path = input_path
|
|
121
|
+
@tempfile = tempfile # ensures that the tempfile will stick around until this image is garbage collected.
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# @return [Boolean]
|
|
125
|
+
def valid?
|
|
126
|
+
# TODO
|
|
127
|
+
true
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def run_command command
|
|
131
|
+
sub = Subexec.run(command, :timeout => Giftrim.timeout)
|
|
132
|
+
if sub.exitstatus == 0
|
|
133
|
+
sub.output
|
|
134
|
+
else
|
|
135
|
+
raise Error, "Command (#{command.inspect.gsub("\\", "")}) failed: #{{:status_code => sub.exitstatus, :output => sub.output}.inspect}"
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Modified from MiniMagick, see License_MiniMagick
|
|
140
|
+
# Writes the temporary file out to either a file location (by passing in a String) or by
|
|
141
|
+
# passing in a Stream that you can #write(chunk) to repeatedly
|
|
142
|
+
#
|
|
143
|
+
# @param output_to [IOStream, String] Some kind of stream object that needs to be read or a file path as a String
|
|
144
|
+
# @return [IOStream, Boolean] If you pass in a file location [String] then you get a success boolean. If its a stream, you get it back.
|
|
145
|
+
# Writes the temporary image that we are using for processing to the output path
|
|
146
|
+
def write(output_to)
|
|
147
|
+
if output_to.kind_of?(String) || !output_to.respond_to?(:write)
|
|
148
|
+
FileUtils.copy_file @path, output_to
|
|
149
|
+
run_command "identify #{output_to}" # Verify that we have a good image
|
|
150
|
+
else # stream
|
|
151
|
+
File.open(@path, "rb") do |f|
|
|
152
|
+
f.binmode
|
|
153
|
+
while chunk = f.read(8192)
|
|
154
|
+
output_to.write(chunk)
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
output_to
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def number_of_frames
|
|
162
|
+
command = "gifsicle --info #{@path}"
|
|
163
|
+
output = run_command command
|
|
164
|
+
if output
|
|
165
|
+
first_line = output.lines.first
|
|
166
|
+
number_of_frames = first_line.scan(/\d+[ \t]*images/).first.to_i
|
|
167
|
+
end
|
|
168
|
+
number_of_frames
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def trim
|
|
172
|
+
# --batch to modify the GIF file in place (not working for frames)
|
|
173
|
+
frames = Giftrim::frame_number_wanted self.number_of_frames, 10
|
|
174
|
+
frames_formatted = frames.map{|frame| "\"##{frame}\""}.join " "
|
|
175
|
+
|
|
176
|
+
@outfile = Tempfile.new('giftrim_')
|
|
177
|
+
@outfile.binmode
|
|
178
|
+
@outfile.close
|
|
179
|
+
|
|
180
|
+
command = "gifsicle --resize-fit '300x300' #{@path} #{frames_formatted} > #{@outfile.path}"
|
|
181
|
+
output = run_command command
|
|
182
|
+
if output
|
|
183
|
+
@tempfile = @outfile
|
|
184
|
+
@path = @tempfile.path
|
|
185
|
+
@outfile = nil
|
|
186
|
+
end
|
|
187
|
+
output
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
data/test/gifs/0.gif
ADDED
|
Binary file
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require_relative "test_helper"
|
|
2
|
+
require File.expand_path('../../lib/giftrim.rb', __FILE__)
|
|
3
|
+
|
|
4
|
+
describe Giftrim do
|
|
5
|
+
it "must return frames wanted" do
|
|
6
|
+
frames = Giftrim::frame_number_wanted 30, 20
|
|
7
|
+
frames.length.must_equal 20
|
|
8
|
+
frames.must_equal [0, 1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 15, 17, 18, 20, 21, 23, 24, 26, 27]
|
|
9
|
+
|
|
10
|
+
target_number = 20
|
|
11
|
+
(20..40).to_a.each do |i|
|
|
12
|
+
frames = Giftrim::frame_number_wanted i, target_number
|
|
13
|
+
frames.length.must_be :<=, target_number
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
describe "when number of frames is smaller than the target number" do
|
|
18
|
+
it "must return frames to be removed" do
|
|
19
|
+
frames = Giftrim::frame_number_wanted 10, 20
|
|
20
|
+
frames.must_equal [0, 1, 2, 3, 4, 5, 6, 7, 8]
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "must get the number of frames" do
|
|
25
|
+
image = Giftrim::Image.open "test/gifs/0.gif"
|
|
26
|
+
image.number_of_frames.must_equal 10
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "should trim a gif" do
|
|
30
|
+
Giftrim.timeout = 10
|
|
31
|
+
|
|
32
|
+
Dir.glob("test/gifs/*.gif").each do |file|
|
|
33
|
+
image = Giftrim::Image.open file
|
|
34
|
+
image.trim
|
|
35
|
+
image.number_of_frames.must_be :<=, 10
|
|
36
|
+
image.number_of_frames.must_be :>=, 1
|
|
37
|
+
image.write "test/gifs/output/#{File.basename(file)}"
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: giftrim
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Leo Lou
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2013-04-04 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: bundler
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ~>
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '1.3'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ~>
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '1.3'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rake
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ! '>='
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ! '>='
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: simplecov
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ~>
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0.7'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ~>
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0.7'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: simplecov-gem-adapter
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ~>
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: 1.0.1
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ~>
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: 1.0.1
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: subexec
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - ~>
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: 0.2.2
|
|
76
|
+
type: :runtime
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - ~>
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: 0.2.2
|
|
83
|
+
description: GIF optimizations using gifsicle
|
|
84
|
+
email:
|
|
85
|
+
- louyuhong@gmail.com
|
|
86
|
+
executables: []
|
|
87
|
+
extensions: []
|
|
88
|
+
extra_rdoc_files: []
|
|
89
|
+
files:
|
|
90
|
+
- .gitignore
|
|
91
|
+
- Gemfile
|
|
92
|
+
- LICENSE.txt
|
|
93
|
+
- LICENSE_MiniMagick.txt
|
|
94
|
+
- README.md
|
|
95
|
+
- Rakefile
|
|
96
|
+
- giftrim.gemspec
|
|
97
|
+
- lib/core_ext/array.rb
|
|
98
|
+
- lib/giftrim.rb
|
|
99
|
+
- lib/giftrim/version.rb
|
|
100
|
+
- test/gifs/0.gif
|
|
101
|
+
- test/giftrim_test.rb
|
|
102
|
+
- test/test_helper.rb
|
|
103
|
+
homepage: https://github.com/l4u/giftrim
|
|
104
|
+
licenses:
|
|
105
|
+
- MIT
|
|
106
|
+
metadata: {}
|
|
107
|
+
post_install_message:
|
|
108
|
+
rdoc_options: []
|
|
109
|
+
require_paths:
|
|
110
|
+
- lib
|
|
111
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
112
|
+
requirements:
|
|
113
|
+
- - ! '>='
|
|
114
|
+
- !ruby/object:Gem::Version
|
|
115
|
+
version: '0'
|
|
116
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
117
|
+
requirements:
|
|
118
|
+
- - ! '>='
|
|
119
|
+
- !ruby/object:Gem::Version
|
|
120
|
+
version: '0'
|
|
121
|
+
requirements: []
|
|
122
|
+
rubyforge_project:
|
|
123
|
+
rubygems_version: 2.0.3
|
|
124
|
+
signing_key:
|
|
125
|
+
specification_version: 4
|
|
126
|
+
summary: GIF optimizations using gifsicle
|
|
127
|
+
test_files:
|
|
128
|
+
- test/gifs/0.gif
|
|
129
|
+
- test/giftrim_test.rb
|
|
130
|
+
- test/test_helper.rb
|