ffi-gmagick 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 +7 -0
- data/.gitignore +18 -0
- data/.travis.yml +8 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +56 -0
- data/Rakefile +12 -0
- data/ffi-gmagick.gemspec +30 -0
- data/lib/ffi/gmagick/image.rb +253 -0
- data/lib/ffi/gmagick/struct.rb +16 -0
- data/lib/ffi/gmagick/version.rb +5 -0
- data/lib/ffi/gmagick.rb +138 -0
- data/test/image_test.rb +79 -0
- data/test/test_helper.rb +5 -0
- metadata +106 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c44392e5977b3e429dc8c977131f5223cf391554
|
4
|
+
data.tar.gz: 4e169e7a89e4ece9154c8a930cdf53ad50104870
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a28e768fd12e76ccc36f0d193b54f5010e660add60ba10a241a65e70f8d21327ee490681e93a924fbb8254c72b932054d5d931917c94ab89de8d5227351f55e8
|
7
|
+
data.tar.gz: 598a9f18be1265c25ec7a23ce90d6dfc5c30ec68ab59f5db41d82f8f3790939217c9619d4056aa48171d6d2368cb07dcc44779fe49278030ed0b2cf037d88187
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Richard Hurt
|
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.
|
data/README.md
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# FFI::GMagick
|
2
|
+
|
3
|
+
FFI wrapper for the GraphicsMagick image processing library.
|
4
|
+
|
5
|
+
## Introduction
|
6
|
+
|
7
|
+
This Gem provides an FFI wrapper for the GraphicsMagick image processing library. All of the
|
8
|
+
other *Magick Gems I found either only worked with ImageMagick or were simply wrappers around
|
9
|
+
the command line interfaces. These are great Gems but I needed to work with images in RAM
|
10
|
+
and not hit the hard drive at all. So, I created this Gem to allow me to work with images
|
11
|
+
completely in RAM without touching the file system at all.
|
12
|
+
|
13
|
+
[](https://travis-ci.org/rnhurt/ffi-gmagick)
|
14
|
+
|
15
|
+
## Installation
|
16
|
+
|
17
|
+
Add this line to your application's Gemfile:
|
18
|
+
|
19
|
+
gem 'ffi-gmagick'
|
20
|
+
|
21
|
+
And then execute:
|
22
|
+
|
23
|
+
$ bundle
|
24
|
+
|
25
|
+
Or install it yourself as:
|
26
|
+
|
27
|
+
$ gem install ffi-gmagick
|
28
|
+
|
29
|
+
You also must have a recent version of GraphicsMagick installed and the library in your
|
30
|
+
systems load path. Don't worry about the load path, most installers do that for you.
|
31
|
+
|
32
|
+
## Usage
|
33
|
+
|
34
|
+
Basic usage is as following:
|
35
|
+
|
36
|
+
require 'ffi/gmagick'
|
37
|
+
|
38
|
+
WATERMARK = FFI::GMagick::Image.new
|
39
|
+
WATERMARK.from_blob(File.open("watermark.png").read)
|
40
|
+
|
41
|
+
image = FFI::GMagick::Image.new
|
42
|
+
image.from_blob(File.open("./my_picture.jpg").read)
|
43
|
+
|
44
|
+
new_thumbnail = image.thumbnail(100, 100, true)
|
45
|
+
new_thumbnail.compose(WATERMARK)
|
46
|
+
|
47
|
+
new_thumbnail.to_file("./my_thumb.jpg")
|
48
|
+
|
49
|
+
|
50
|
+
## Contributing
|
51
|
+
|
52
|
+
1. Fork it
|
53
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
54
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
55
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
56
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/ffi-gmagick.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'ffi/gmagick/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "ffi-gmagick"
|
8
|
+
spec.version = FFI::GMagick::VERSION
|
9
|
+
spec.authors = ["Richard Hurt"]
|
10
|
+
spec.email = ["rnhurt@gmail.com"]
|
11
|
+
spec.summary = "Use the C GraphicsMagick bindings to provide a Ruby interface"
|
12
|
+
spec.description = "This is not a simple 'Ruby'-like implementation. It is more of a
|
13
|
+
raw 'C' implementation. As such, it may be a bit more difficult to
|
14
|
+
work with than something like rmagick, but it should perform just as
|
15
|
+
well."
|
16
|
+
spec.homepage = "https://github.com/rnhurt/ffi-gmagick"
|
17
|
+
spec.license = "MIT"
|
18
|
+
|
19
|
+
spec.files = `git ls-files`.split($/)
|
20
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
21
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
spec.requirements << 'libGraphicsMagick, v1.3.18'
|
25
|
+
|
26
|
+
spec.add_runtime_dependency 'ffi', '~> 1.9'
|
27
|
+
|
28
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
29
|
+
spec.add_development_dependency "rake"
|
30
|
+
end
|
@@ -0,0 +1,253 @@
|
|
1
|
+
module FFI
|
2
|
+
module GMagick
|
3
|
+
class Image
|
4
|
+
# This is a convenience class that takes care of most of the messy work
|
5
|
+
# of dealing with the raw FFI::GMagick interface.
|
6
|
+
#
|
7
|
+
# Basic usage is as following:
|
8
|
+
#
|
9
|
+
# require 'ffi/gmagick'
|
10
|
+
#
|
11
|
+
# WATERMARK = FFI::GMagick::Image.new
|
12
|
+
# WATERMARK.from_blob(File.open("watermark.png").read)
|
13
|
+
#
|
14
|
+
# image = FFI::GMagick::Image.new
|
15
|
+
# image.from_blob(File.open("./my_picture.jpg").read)
|
16
|
+
#
|
17
|
+
# new_thumbnail = image.thumbnail(100, 100, true)
|
18
|
+
# new_thumbnail.compose(WATERMARK)
|
19
|
+
#
|
20
|
+
# new_thumbnail.to_file("./my_thumb.jpg")
|
21
|
+
#
|
22
|
+
# This will open two images, a picture and a watermark, create a square
|
23
|
+
# thumbnail and apply the watermark in the center of the image.
|
24
|
+
attr_accessor :wand, :status
|
25
|
+
|
26
|
+
def initialize(old_wand=nil)
|
27
|
+
if old_wand
|
28
|
+
@wand = FFI::GMagick.CloneMagickWand( old_wand )
|
29
|
+
else
|
30
|
+
@wand ||= FFI::GMagick.NewMagickWand
|
31
|
+
end
|
32
|
+
@status = 1
|
33
|
+
end
|
34
|
+
|
35
|
+
# Read image data from a BLOB
|
36
|
+
def from_blob(blob)
|
37
|
+
@status = FFI::GMagick.MagickReadImageBlob( @wand, blob, blob.bytesize)
|
38
|
+
|
39
|
+
# Note: PDF images don't report proper bytesize
|
40
|
+
return blob.bytesize
|
41
|
+
end
|
42
|
+
|
43
|
+
# Write image data to a BLOB
|
44
|
+
def to_blob
|
45
|
+
output = nil
|
46
|
+
FFI::MemoryPointer.new(:ulong, 64) do |length|
|
47
|
+
blobout = FFI::GMagick.MagickWriteImageBlob( @wand, length )
|
48
|
+
output = blobout.read_string(length.read_long)
|
49
|
+
end
|
50
|
+
return output
|
51
|
+
end
|
52
|
+
|
53
|
+
# Read image data from a filename
|
54
|
+
def from_file(filename)
|
55
|
+
blob = File.open(filename).read
|
56
|
+
self.from_blob(blob)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Write image data to a filename
|
60
|
+
def to_file(filename)
|
61
|
+
@status = FFI::GMagick.MagickWriteImage( @wand, filename )
|
62
|
+
end
|
63
|
+
|
64
|
+
# Return the width of the image in pixels
|
65
|
+
def width
|
66
|
+
FFI::GMagick.MagickGetImageWidth( @wand ).to_f
|
67
|
+
end
|
68
|
+
alias_method :cols, :width
|
69
|
+
|
70
|
+
# Return the height of the image in pixels
|
71
|
+
def height
|
72
|
+
FFI::GMagick.MagickGetImageHeight( @wand ).to_f
|
73
|
+
end
|
74
|
+
alias_method :rows, :height
|
75
|
+
|
76
|
+
# Return the size of the image in bytes
|
77
|
+
def size
|
78
|
+
FFI::GMagick.MagickGetImageSize( @wand )
|
79
|
+
end
|
80
|
+
alias_method :length, :size
|
81
|
+
|
82
|
+
# Return the image format
|
83
|
+
def format
|
84
|
+
FFI::GMagick.MagickGetImageFormat( @wand )
|
85
|
+
end
|
86
|
+
|
87
|
+
# Set the image format
|
88
|
+
def format=(format)
|
89
|
+
FFI::GMagick.MagickSetImageFormat( @wand, format )
|
90
|
+
end
|
91
|
+
|
92
|
+
# Negate the colors in the specified channel
|
93
|
+
def negate_channel(channel, gray=0)
|
94
|
+
@status = FFI::GMagick.MagickNegateImageChannel( @wand, channel, gray )
|
95
|
+
end
|
96
|
+
|
97
|
+
# Set the gamma value for the specified channel
|
98
|
+
def gamma_channel(channel, gamma=0)
|
99
|
+
@status = FFI::GMagick.MagickGammaImageChannel( @wand, channel, gamma )
|
100
|
+
end
|
101
|
+
|
102
|
+
# Return the value of the named attribute
|
103
|
+
def attribute(name)
|
104
|
+
FFI::GMagick.MagickGetImageAttribute( @wand, name )
|
105
|
+
end
|
106
|
+
|
107
|
+
# Return the image type
|
108
|
+
def type
|
109
|
+
FFI::GMagick.MagickGetImageType( @wand )
|
110
|
+
end
|
111
|
+
|
112
|
+
# Set the image type to one of the valid
|
113
|
+
# <a href="http://www.graphicsmagick.org/api/types.html#imagetype">image types</a>
|
114
|
+
def type=(type)
|
115
|
+
@status = FFI::GMagick.MagickSetImageType( @wand, type )
|
116
|
+
end
|
117
|
+
|
118
|
+
# Return the colorspace
|
119
|
+
def colorspace
|
120
|
+
FFI::GMagick.MagickGetImageColorspace( @wand )
|
121
|
+
end
|
122
|
+
alias_method :colormodel, :colorspace
|
123
|
+
|
124
|
+
# Set the image colorspace to one of the valid
|
125
|
+
# <a href="http://www.graphicsmagick.org/api/types.html#colorspacetype">colorspace types</a>.
|
126
|
+
def colorspace=(colorspace)
|
127
|
+
FFI::GMagick.MagickSetImageColorspace( @wand, colorspace )
|
128
|
+
end
|
129
|
+
alias_method :colormodel=, :colorspace=
|
130
|
+
|
131
|
+
# Return the information for a specific profile in the image
|
132
|
+
def profile(name="ICC")
|
133
|
+
output = nil
|
134
|
+
FFI::MemoryPointer.new(:ulong, 64) do |length|
|
135
|
+
blobout = FFI::GMagick.MagickGetImageProfile( @wand, name, length )
|
136
|
+
output = blobout.read_string(length.read_long)
|
137
|
+
end
|
138
|
+
return output
|
139
|
+
end
|
140
|
+
|
141
|
+
# Add a profile to this image
|
142
|
+
def add_profile(name, profile)
|
143
|
+
@status = FFI::GMagick.MagickProfileImage( @wand, name, profile, profile.size )
|
144
|
+
raise "invalid profile" unless 1 == status
|
145
|
+
end
|
146
|
+
|
147
|
+
# Return the interlace information as one of the valid
|
148
|
+
# <a href="http://www.graphicsmagick.org/api/types.html#interlacetype">interlace types</a>.
|
149
|
+
def interlace
|
150
|
+
FFI::GMagick.MagickGetImageInterlaceScheme( @wand )
|
151
|
+
end
|
152
|
+
|
153
|
+
# Set the interlace information to one of the valid
|
154
|
+
# <a href="http://www.graphicsmagick.org/api/types.html#interlacetype">interlace types</a>.
|
155
|
+
def interlace=(interlace)
|
156
|
+
@status = FFI::GMagick.MagickSetImageInterlaceScheme( @wand, interlace )
|
157
|
+
raise "invalid interlace type" unless 1 == status
|
158
|
+
end
|
159
|
+
|
160
|
+
# Strip the image of extra data (comments, profiles, etc.)
|
161
|
+
def strip
|
162
|
+
@status = FFI::GMagick.MagickStripImage( @wand )
|
163
|
+
end
|
164
|
+
|
165
|
+
def quality=(quality)
|
166
|
+
@status = FFI::GMagick.MagickSetCompressionQuality( @wand, quality )
|
167
|
+
end
|
168
|
+
|
169
|
+
# Resize the image to the desired dimensions using various
|
170
|
+
# <a href="http://www.graphicsmagick.org/api/types.html#filtertypes">filters</a>.
|
171
|
+
def resize(width, height, filter=:BoxFilter, blur=1.0)
|
172
|
+
@status = FFI::GMagick.MagickResizeImage( @wand, width, height, filter, blur )
|
173
|
+
end
|
174
|
+
|
175
|
+
|
176
|
+
# Crop the image to the desired dimensions. If you don't provide an
|
177
|
+
# X,Y offset the crop will be centered.
|
178
|
+
def crop(width, height, x=nil, y=nil)
|
179
|
+
if x.nil? || y.nil?
|
180
|
+
old_width = self.width
|
181
|
+
old_height = self.height
|
182
|
+
|
183
|
+
x = (old_width / 2) - (width / 2)
|
184
|
+
y = (old_height / 2) - (height / 2)
|
185
|
+
end
|
186
|
+
|
187
|
+
@status = FFI::GMagick.MagickCropImage( @wand, width, height, x, y )
|
188
|
+
end
|
189
|
+
|
190
|
+
# A convenience method. Resize the image to fit within the specified
|
191
|
+
# dimensions while retaining the aspect ratio of the original image.
|
192
|
+
# If necessary, crop the image in the larger dimension.
|
193
|
+
#
|
194
|
+
# Returns a new image object
|
195
|
+
def resize_to_fill(new_width, new_height=nil)
|
196
|
+
new_height ||= new_width
|
197
|
+
local_image = FFI::GMagick::Image.new(@wand)
|
198
|
+
|
199
|
+
if new_width != local_image.width || new_height != local_image.height
|
200
|
+
scale = [new_width/local_image.width.to_f, new_height/local_image.height.to_f].max
|
201
|
+
local_image.resize(scale*width+0.5, scale*height+0.5)
|
202
|
+
end
|
203
|
+
|
204
|
+
if new_width != local_image.width || new_height != local_image.height
|
205
|
+
local_image.crop(new_width, new_height)
|
206
|
+
end
|
207
|
+
|
208
|
+
return local_image
|
209
|
+
end
|
210
|
+
|
211
|
+
# A convenience method. Resize the image to fit within the
|
212
|
+
# specified dimensions while retaining the original aspect
|
213
|
+
# ratio. The image may be shorter or narrower than specified
|
214
|
+
# in the smaller dimension but will not be larger than the
|
215
|
+
# specified values.
|
216
|
+
#
|
217
|
+
# Returns a new image object
|
218
|
+
def resize_to_fit(width, height=nil)
|
219
|
+
height ||= width
|
220
|
+
geometry = "#{width}x#{height}>"
|
221
|
+
local_wand = FFI::GMagick.MagickTransformImage( @wand, "", geometry )
|
222
|
+
return FFI::GMagick::Image.new(local_wand)
|
223
|
+
end
|
224
|
+
|
225
|
+
# Composites an Image (such as a watermark) with this one using various
|
226
|
+
# <a href="http://www.graphicsmagick.org/api/types.html#compositeoperator">composite operators</a>.
|
227
|
+
#
|
228
|
+
# If you don't provide an X,Y offset then the operation with be centered on the base image.
|
229
|
+
def compose(image, operator=:OverCompositeOp, x=nil, y=nil)
|
230
|
+
if x.nil? || y.nil?
|
231
|
+
width = self.width
|
232
|
+
height = self.height
|
233
|
+
new_width = image.width
|
234
|
+
new_height = image.height
|
235
|
+
|
236
|
+
x = (width / 2) - (new_width / 2)
|
237
|
+
y = (height / 2) - (new_height / 2)
|
238
|
+
end
|
239
|
+
@status = FFI::GMagick.MagickCompositeImage(@wand, image.wand, operator, x, y)
|
240
|
+
end
|
241
|
+
|
242
|
+
# Is this a valid image
|
243
|
+
def valid?
|
244
|
+
@status == 1
|
245
|
+
end
|
246
|
+
|
247
|
+
# Return the copywrite notification for GraphicsMagick
|
248
|
+
def copywrite
|
249
|
+
FFI::GMagick.MagickGetCopyright
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module FFI
|
2
|
+
module GMagick
|
3
|
+
class PixelPacket < FFI::Struct
|
4
|
+
layout :red, :uint,
|
5
|
+
:green, :uint,
|
6
|
+
:blue, :uint,
|
7
|
+
:opacity, :uint
|
8
|
+
end
|
9
|
+
|
10
|
+
class ImageInfo < FFI::Struct
|
11
|
+
layout :adjoin, :uint,
|
12
|
+
:antialias, :uint,
|
13
|
+
:background_color, PixelPacket.ptr
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/ffi/gmagick.rb
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
require "ffi"
|
2
|
+
require "ffi/gmagick/image"
|
3
|
+
require "ffi/gmagick/version"
|
4
|
+
|
5
|
+
module FFI
|
6
|
+
# FFI::GMagick is an FFI binding for the GraphicsMagick MagickWand image library.
|
7
|
+
# Basic usage is as following:
|
8
|
+
#
|
9
|
+
# require 'ffi/gmagick'
|
10
|
+
#
|
11
|
+
# wand = FFI::GMagick.NewMagickWand
|
12
|
+
# FFI::GMagick.MagickReadImage( wand, "./test.jpg")
|
13
|
+
#
|
14
|
+
# FFI::GMagick.MagickSetImageFormat( wand, "PNG" )
|
15
|
+
#
|
16
|
+
# FFI::GMagick.MagickResizeImage( wand, 500, 500, :UndefinedFilter, 0.0)
|
17
|
+
# FFI::GMagick.MagickWriteImage( wand, "./test-out.jpg" )
|
18
|
+
#
|
19
|
+
# For more information on commands and syntax see http://www.graphicsmagick.org/wand/magick_wand.html
|
20
|
+
#
|
21
|
+
module GMagick
|
22
|
+
extend FFI::Library
|
23
|
+
ffi_lib "GraphicsMagickWand"
|
24
|
+
|
25
|
+
enum :interlace_type, [:UndefinedInterlace, :NoInterlace, :LineInterlace, :PlaneInterlace, :PartitionInterlace]
|
26
|
+
|
27
|
+
enum :filter_type, [:UndefinedFilter, :PointFilter, :BoxFilter, :TriangleFilter,
|
28
|
+
:HermiteFilter, :HanningFilter, :HammingFilter, :BlackmanFilter,
|
29
|
+
:GaussianFilter, :QuadraticFilter, :CubicFilter, :CatromFilter,
|
30
|
+
:MitchellFilter, :LanczosFilter, :BesselFilter, :SincFilter]
|
31
|
+
enum :channel_type, [:UndefinedChannel, :RedChannel, :CyanChannel, :GreenChannel, :MagentaChannel,
|
32
|
+
:BlueChannel, :YellowChannel, :OpacityChannel, :BlackChannel, :MatteChannel,
|
33
|
+
:AllChannels, :GrayChannel]
|
34
|
+
|
35
|
+
enum :image_type, [:UndefinedType, :BilevelType, :GrayscaleType, :PaletteType, :PaletteMatteType,
|
36
|
+
:TrueColorType, :TrueColorMatteType, :ColorSeparationType]
|
37
|
+
|
38
|
+
enum :colorspace, [:UndefinedColorspace, :RGBColorspace, :GRAYColorspace,
|
39
|
+
:TransparentColorspace, :OHTAColorspace, :XYZColorspace, :YCCColorspace,
|
40
|
+
:YIQColorspace, :YPbPrColorspace, :YUVColorspace, :CMYKColorspace,
|
41
|
+
:sRGBColorspace, :HSLColorspace, :HWBColorspace, :LABColorspace,
|
42
|
+
:CineonLogRGBColorspace, :Rec601LumaColorspace, :Rec601YCbCrColorspace,
|
43
|
+
:Rec709LumaColorspace, :Rec709YCbCrColorspace]
|
44
|
+
|
45
|
+
enum :gravity_type, [:ForgetGravity, :NorthWestGravity, :NorthGravity, :NorthEastGravity,
|
46
|
+
:WestGravity, :CenterGravity, :EastGravity, :SouthWestGravity,
|
47
|
+
:SouthGravity, :SouthEastGravity]
|
48
|
+
|
49
|
+
enum :composite_operator, [:UndefinedCompositeOp, :OverCompositeOp, :InCompositeOp, :OutCompositeOp,
|
50
|
+
:AtopCompositeOp, :XorCompositeOp, :PlusCompositeOp, :MinusCompositeOp,
|
51
|
+
:AddCompositeOp, :SubtractCompositeOp, :DifferenceCompositeOp, :BumpmapCompositeOp,
|
52
|
+
:CopyCompositeOp, :CopyRedCompositeOp, :CopyGreenCompositeOp, :CopyBlueCompositeOp,
|
53
|
+
:CopyOpacityCompositeOp, :ClearCompositeOp, :DissolveCompositeOp, :DisplaceCompositeOp,
|
54
|
+
:ModulateCompositeOp, :ThresholdCompositeOp, :NoCompositeOp, :DarkenCompositeOp,
|
55
|
+
:LightenCompositeOp, :HueCompositeOp, :SaturateCompositeOp, :ColorizeCompositeOp,
|
56
|
+
:LuminizeCompositeOp, :ScreenCompositeOp, :OverlayCompositeOp, :CopyCyanCompositeOp,
|
57
|
+
:CopyMagentaCompositeOp, :CopyYellowCompositeOp, :CopyBlackCompositeOp, :DivideCompositeOp]
|
58
|
+
|
59
|
+
typedef :pointer, :wand
|
60
|
+
typedef :pointer, :composite_wand
|
61
|
+
typedef :pointer, :blob
|
62
|
+
typedef :pointer, :profile
|
63
|
+
typedef :string, :name
|
64
|
+
typedef :string, :filename
|
65
|
+
typedef :string, :format
|
66
|
+
typedef :string, :geometry
|
67
|
+
typedef :string, :crop
|
68
|
+
typedef :uint, :magick_pass_fail
|
69
|
+
typedef :uint, :dither
|
70
|
+
typedef :uint, :measure_error
|
71
|
+
typedef :uint, :gray
|
72
|
+
typedef :ulong, :columns
|
73
|
+
typedef :ulong, :rows
|
74
|
+
typedef :ulong, :depth
|
75
|
+
typedef :ulong, :quality
|
76
|
+
typedef :ulong, :width
|
77
|
+
typedef :ulong, :height
|
78
|
+
typedef :ulong, :number_colors
|
79
|
+
typedef :ulong, :tree_depth
|
80
|
+
typedef :long, :x
|
81
|
+
typedef :long, :y
|
82
|
+
typedef :double, :blur
|
83
|
+
typedef :double, :radius
|
84
|
+
typedef :double, :sigma
|
85
|
+
typedef :double, :gamma
|
86
|
+
typedef :double, :amount
|
87
|
+
typedef :double, :threshold
|
88
|
+
typedef :double, :x_resolution
|
89
|
+
typedef :double, :y_resolution
|
90
|
+
typedef :size_t, :length
|
91
|
+
|
92
|
+
|
93
|
+
|
94
|
+
attach_function :NewMagickWand, [], :wand
|
95
|
+
attach_function :CloneMagickWand, [ :wand ], :wand
|
96
|
+
|
97
|
+
attach_function :MagickReadImage, [ :wand, :filename ], :magick_pass_fail
|
98
|
+
attach_function :MagickReadImageBlob, [ :wand, :blob, :length ], :magick_pass_fail
|
99
|
+
attach_function :MagickWriteImage, [ :wand, :filename ], :magick_pass_fail
|
100
|
+
attach_function :MagickWriteImageBlob, [ :wand, :pointer ], :pointer
|
101
|
+
|
102
|
+
attach_function :MagickGetImageFormat, [ :wand ], :string
|
103
|
+
attach_function :MagickSetImageFormat, [ :wand, :format ], :uint
|
104
|
+
attach_function :MagickGetImageHeight, [ :wand ], :ulong
|
105
|
+
attach_function :MagickGetImageWidth, [ :wand ], :ulong
|
106
|
+
attach_function :MagickGetImageType, [ :wand ], :image_type
|
107
|
+
attach_function :MagickSetImageType, [ :wand, :image_type ], :magick_pass_fail
|
108
|
+
attach_function :MagickGetImageAttribute, [ :wand, :string ], :string
|
109
|
+
attach_function :MagickGetImageColorspace, [ :wand ], :colorspace
|
110
|
+
attach_function :MagickSetImageColorspace, [ :wand, :colorspace ], :magick_pass_fail
|
111
|
+
attach_function :MagickGetImageDepth, [ :wand ], :depth
|
112
|
+
attach_function :MagickSetImageDepth, [ :wand, :depth ], :magick_pass_fail
|
113
|
+
attach_function :MagickGetImageSize, [ :wand ], :ulong
|
114
|
+
|
115
|
+
attach_function :MagickSetCompressionQuality, [ :wand, :quality ], :magick_pass_fail
|
116
|
+
attach_function :MagickStripImage, [ :wand ], :magick_pass_fail
|
117
|
+
attach_function :MagickUnsharpMaskImage, [ :wand, :radius, :sigma, :amount, :threshold ], :magick_pass_fail
|
118
|
+
attach_function :MagickQuantizeImage, [ :wand, :number_colors, :colorspace, :tree_depth, :dither, :measure_error ], :magick_pass_fail
|
119
|
+
attach_function :MagickNegateImageChannel, [ :wand, :channel_type, :gray ], :magick_pass_fail
|
120
|
+
attach_function :MagickGammaImageChannel, [ :wand, :channel_type, :gamma ], :magick_pass_fail
|
121
|
+
attach_function :MagickProfileImage, [ :wand, :name, :profile, :length], :magick_pass_fail
|
122
|
+
attach_function :MagickGetImageProfile, [ :wand, :name, :profile ], :profile
|
123
|
+
attach_function :MagickSetImageProfile, [ :wand, :name, :profile, :ulong ], :magick_pass_fail
|
124
|
+
attach_function :MagickGetImageInterlaceScheme, [ :wand ], :interlace_type
|
125
|
+
attach_function :MagickSetImageInterlaceScheme, [ :wand, :interlace_type ], :magick_pass_fail
|
126
|
+
|
127
|
+
attach_function :MagickResizeImage, [ :wand, :columns, :rows, :filter_type, :blur ], :magick_pass_fail
|
128
|
+
attach_function :MagickResampleImage, [ :wand, :x_resolution, :y_resolution, :filter_type, :blur ], :magick_pass_fail
|
129
|
+
attach_function :MagickTransformImage, [ :wand, :crop, :geometry ], :wand
|
130
|
+
attach_function :MagickScaleImage, [ :wand, :columns, :rows ], :magick_pass_fail
|
131
|
+
attach_function :MagickCropImage, [ :wand, :width, :height, :x, :y ], :magick_pass_fail
|
132
|
+
attach_function :MagickCompositeImage, [ :wand, :composite_wand, :composite_operator, :x, :y ], :magick_pass_fail
|
133
|
+
|
134
|
+
attach_function :MagickGetConfigureInfo, [ :wand, :string ], :string
|
135
|
+
attach_function :MagickGetVersion, [ :pointer ], :string
|
136
|
+
attach_function :MagickGetCopyright, [], :string
|
137
|
+
end
|
138
|
+
end
|
data/test/image_test.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ImageTest < MiniTest::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@image = FFI::GMagick::Image.new()
|
6
|
+
@image.from_blob(BLOB)
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_size
|
10
|
+
assert_equal 2005, @image.size, "BLOBs are not equal"
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_crop
|
14
|
+
@image.crop(10,10)
|
15
|
+
assert_equal 10, @image.width, "invalid width"
|
16
|
+
assert_equal 10, @image.height, "invalid height"
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_crop_with_offset
|
20
|
+
@image.crop(10,10, 5, 15)
|
21
|
+
assert_equal 10, @image.width, "invalid width"
|
22
|
+
assert_equal 10, @image.height, "invalid height"
|
23
|
+
# TODO: How do you test offsets??
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_resize
|
27
|
+
@image.resize(10,20)
|
28
|
+
assert_equal 10, @image.width, "invalid width"
|
29
|
+
assert_equal 20, @image.height, "invalid height"
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_resize_to_fill
|
33
|
+
new_image = @image.resize_to_fill(100,200)
|
34
|
+
assert_equal 100, new_image.width, "invalid width"
|
35
|
+
assert_equal 200, new_image.height, "invalid height"
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_resize_to_fill_by_width
|
39
|
+
new_image = @image.resize_to_fill(100)
|
40
|
+
assert_equal 100, new_image.width, "invalid width"
|
41
|
+
assert_equal 100, new_image.height, "invalid height"
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_resize_to_fit
|
45
|
+
new_image = @image.resize_to_fit(100,200)
|
46
|
+
assert_equal 100, new_image.width, "invalid width"
|
47
|
+
assert_equal 63, new_image.height, "invalid height"
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_resize_to_fit_by_width
|
51
|
+
new_image = @image.resize_to_fit(100)
|
52
|
+
assert_equal 100, new_image.width, "invalid width"
|
53
|
+
assert_equal 63, new_image.height, "invalid height"
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_colorspace
|
57
|
+
assert_equal :RGBColorspace, @image.colorspace, "invalid color space"
|
58
|
+
assert_equal :RGBColorspace, @image.colormodel, "invalid color model"
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_get_type
|
62
|
+
assert_equal :TrueColorMatteType, @image.type, "invalid type"
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_set_type
|
66
|
+
skip # not yet working
|
67
|
+
@image.type = :TrueColorType
|
68
|
+
assert @image.valid?
|
69
|
+
assert_equal :TrueColorType, @image.type, "invalid type"
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_strip
|
73
|
+
skip # not yet working
|
74
|
+
old_size = @image.size
|
75
|
+
@image.strip
|
76
|
+
assert @image.valid?
|
77
|
+
assert old_size > @image.size, "image is not smaller"
|
78
|
+
end
|
79
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,5 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'ffi/gmagick'
|
3
|
+
|
4
|
+
# JPEG 150x94+0+0 DirectClass 8-bit 2.0K (2,005 bytes) TrueColorMatteType
|
5
|
+
BLOB = "\xFF\xD8\xFF\xE0\u0000\u0010JFIF\u0000\u0001\u0001\u0001\u0000H\u0000H\u0000\u0000\xFF\xFE\u0000\u0013This is a comment\xFF\xDB\u0000C\u0000\b\u0006\u0006\a\u0006\u0005\b\a\a\a\t\t\b\n\f\u0014\r\f\v\v\f\u0019\u0012\u0013\u000F\u0014\u001D\u001A\u001F\u001E\u001D\u001A\u001C\u001C $.' \",#\u001C\u001C(7),01444\u001F'9=82<.342\xFF\xDB\u0000C\u0001\t\t\t\f\v\f\u0018\r\r\u00182!\u001C!22222222222222222222222222222222222222222222222222\xFF\xC0\u0000\u0011\b\u0000^\u0000\x96\u0003\u0001\"\u0000\u0002\u0011\u0001\u0003\u0011\u0001\xFF\xC4\u0000\u001C\u0000\u0000\u0002\u0002\u0003\u0001\u0001\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0005\u0003\u0004\u0006\a\b\u0002\u0001\xFF\xC4\u0000B\u0010\u0000\u0001\u0002\u0003\u0002\b\v\u0004\a\t\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0003\u0002\u0004\u0005\u0006\u0011\u0012\u0016!14qr\xB1\a236AQt\x81\x93\x94\xC1\u0015TU\xB2#57Va\x92\xD1\u0013\u0017$BRs\x91\xA1\xE1\xFF\xC4\u0000\e\u0001\u0000\u0002\u0003\u0001\u0001\u0001\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0006\a\u0000\u0004\u0005\u0003\u0002\u0001\xFF\xC4\u00004\u0011\u0000\u0002\u0000\u0003\u0003\b\t\u0004\u0003\u0001\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0002\u0003\u0004\u00064q\u0005\u0011\u0013!13\xB1\xC1\u00142AQRar\x91\xD1\u0012\"5\x81\u0016\x92\xA1S\xFF\xDA\u0000\f\u0003\u0001\u0000\u0002\u0011\u0003\u0011\u0000?\u0000\xDB\xC0\u0000B\u001E\xA0\xE3\u0013\u0010\xC1\xC6&\u0001-\u0015\xF7\xF4\xB9\x96\xE4\xF5C\xABP\xBAs\x95\x87dcը]9\xCAòv\xB2ߐX>F=\xA0\xB9<W2\u0000\u0000\u0019\xC0 \x91s\xA8\u0002\xE7P\u0014/i\xA4U\xA8\xE8.wo\u0012&t\xD4;\xA8\xE8.wo\u0012&t\xD43\xACe\xC2/S\xE0\x86u\x8C\xB8E\xEA|\u0010t\t\xAA\x9AD;\u001E\xA3\x9E\x815SH\x87c\xD4\xD4\xCB\xF7'\x8A\r\xA9\xF7\x85 \u0000\u0001\r#\u0018\u007FHwiw\x91\x92?\xA4;\xB4\xBB\xC8ǽ6\xE6\f\u0017\u0004!*w\xD1\xE2\xF8\xB0\u0000\u0002\xC1\xC4\xEA\u0010\u0000\u0013\xC1\t\xEA\u000E11\f\u001Cb`\u0012\xD1_\u007FK\x99nOT:\xB5\v\xA79XvF=Z\x85Ӝ\xAC;'k-\xF9\u0005\x83\xE4c\xDA\v\x93\xC5s \u0000\u0001\x9C\u0002\t\u0017:\x80.u\u0001B\xF6\x9AEZ\x8E\x82\xE7v\xF1\"gMC\xBA\x8E\x82\xE7v\xF1\"gMC:\xC6\\\"\xF5>\bgX˄^\xA7\xC1\a@\x9A\xA9\xA4C\xB1\xEA9\xE8\u0013U4\x88v=ML\xBFrx\xA0ڟxR\u0000\u0000\u0010\xD21\x87\xF4\x87v\x97y\u0019#\xFAC\xBBK\xBC\x8C{\xD3n`\xC1pB\u0012\xA7}\u001E/\x8B\u0000\u0000,\u001CN\xA1\u0000\u0001<\u0010\x9E\xA0\xE3\u0013\u0010\xC1\xC6&\u0001-\u0015\xF7\xF4\xB9\x96\xE4\xF5C\xABP\xBAs\x95\x87dcը]9\xCAòv\xB2ߐX>F=\xA0\xB9<W2\u0000\u0000\u0019\xC0 \x91s\xA8\u0002\xE7P\u0014/i\xA4U\xA8\xE8.wo\u0012&t\xD4;\xA8\xE8.wo\u0012&t\xD43\xACe\xC2/S\xE0\x86u\x8C\xB8E\xEA|\u0010t\t\xAA\x9AD;\u001E\xA3\x9E\x815SH\x87c\xD4\xD4\xCB\xF7'\x8A\r\xA9\xF7\x85 \u0000\u0001\r#\u0018\u007FHwiw\x91\x92?\xA4;\xB4\xBB\xC8ǽ6\xE6\f\u0017\u0004!*w\xD1\xE2\xF8\xB0\u0000\u0002\xC1\xC4\xEA\u0010\u0014cU\x9F\xF8\xDD?DŽ1\xAA\xCF\xFCn\x9F\xE3\xC2):4\xFF\u0000\u0003\xF6\u007F\u0006\xFE\x92\u001E\xF1\xCC\u001Cbk\x8C~+af؇\r\xCA\xF5:\bs_\u0014\xC4(y\xC7\xCB%\xF7\x96\x95\xE6\xA0\xFD@[EK?\xA6\xEE\xDE\xC5\xD8\xFC\xFC\x8Brb_N\xD3!\xBDn\xBC];\xCBC\x913\v\xA1\xB7VY8\xF6\x86\x97\u000E\xB9\xA8?S\xE2\xDA\nEC\xE9\xA4\xEA2\x93\r\xA2\xE0\xACm\xBC\x91%\xFDY\u000E\xB6^\x9El\u0015\xE9\xC5\v\xD8\xFB\u001F\x97\x91\x97\x97%\xC56\x93閳\xBC\xEBf\xBE\u0019\xCBw\x85\xE5Oh\xCA{\xCB\u001E\"\a\xB4\xA4\xFD\xE5\x8F\u0011\u0006O\xD1\u0017p\u001D\xD0*\xBF\xE5\u0017\xF5\x8B࠹\xD4\u0004\xABk\xAC\xEA*\xDF[\xA7\xF9\x98\u000F\x98\xDFg~7O\xF3\u0010\ngO7?U\xFB?\x82ւg\x85\xFB?\x81\x85K@wRo\u0012]}עf.E[\xA5U\eYi\n\x84\xAC\xD3\xD1䅦]H\xA2[\xB2\xADȟ\x81\u0014R\u0013\xC9r\xC3$\xE2\xA5\xDFң\"ǭ\u001D\fPǫ\xEE{uv!\x8Be'˧\xA1\x8A\u0019\xB1(_\xD4\xF6\xB4\xBB\u0017{D\u0019\xD1r\t\xEA\xA9\xFCD9\u0013\x89\xEAd)#;\xEE\xAE~E1\x8BE4\xD5:u\xA6\xE7\u001Cn]ț\xC2H]\\\u0015T\xBDr\xE54\xF2\xEBQѸa\xEFA\x855u+\x99\x99L\x87\xFB/\x92\u0000({b\x97\xEF\xF2\xDE\"\a\xB6)~\xFF\u0000-\xE2 \u0011\xA2\x8F\xB8\xD3\xE9R<k\xDD|\x89\xDF\xD2\u001D\xDA]\xE4cx\xAC\xE5ne\u007Fn\xC5\"u\xD6\\\xFAH#\x85\x85T\x8A\u0015ʊ\x8B\xD5pb\xAD\xA0\xF8\u001C\xFF\u0000\x97\x88v\xD3T\xC8Ra\xFB\xD6\xC5ڻ\x97\x98\x90\xA8\x82':-]\xAF\x8B\u0014\u0000\xDF\u0015m\a\xC0\xE7\xFC\xBC@v\xE9R<k\xDD|\x9Ctqw\t\xB0\x93\xAD\u0003\t:Ј\u000FzF|\xCCU\xAB\xC1\u0013\xF28\u0010B\xB1ņ\x8Bre)Sl\x85\xA3\xAC5\e\xD4\xDA4\xEC\xD3PE\x81\u0014L\xB2\xB1\".{\x86\xE6\xF3\xE07\x9B\xD5N؟$ \xAD\xA2\xA2\x85\xC0\xEA\xF3\xEBԳv\u001A\u0014sZz3@\xFE\xEEm\xA6U\xC5z\xAF\x96\x88\xD96\u0016\xCA\xD7\xE9\xD6}\xD6')\u0013\x8C8\xAF\xC5\u0012B\xE3K\n\xDDt9N\x88ȉ\xF8\u001EW.eN\xF0V\x9E{\x91\u001E\x91,\xE6\xCD-TT\xD34\x90\xAC望\xA6O\xC8\xCB957&\xE3,6\x97\xC6\xE3\x90ܐ\xA7Z\xA8\x9A*\xC51Q/\x9E\x97\xFC\xE8m~\u0011~ϫ}\x99w\xA1\xCC+\xAC-\xC9/\xA6\xCAqǫ3ͫ\u0002\xDC\xFBM>SI@\xBF\xD3\u0015\x8EBm\\\x89R]\xCC\xEB\xFC\xA7\x9FgM\xFB\xBB\x9F\x94\xCA\xC0\xF9\xFCfG\x8D\xFF\u0000\x80\xCFN\x8B\xB8\xF3\xC1\xBC\xE4\xAD&\xDE\xC8\xCCT^\x82Y\xA6\xD1Ď7\x97\u0005!\xBD\xB8\x91/\xFF\u0000&\xF9\xC7{.\x991\x82\x9F\u007F\xF7\x90\xE6\u001A\x9F\xD6O.[\xB0\x8A\x99\xD7X12.\x8F6)K^f\xCF5Y6]dJlm\xADGTc͗\xBF%~\x9D㡦\xF8^\xABS\xAB6\x92M\xFAl\xEB3M\xC1&\x90E\u00131a\".\u001Ckw\xFB5Ңߔ\xFBz'\xFCS\x94\xC9\xEE5\x99\xA2Rd\x99t\xB3t\xB0\xC4߱\xE0u/d\xAD\fԻs\u0012\xF4i\xD7Yr\u0014\x8A\b\xE0iU\"Ę%:^\xC7\xF3>\x89\xD8\xDA\xDCp5\u0006\xB4Kefd,\xFD6Nn\xBFObe\x89V\x9Ay\xA7\u001ED\x8A\b\xE1\x85\u0011QS\xA1QQP\xBF\x8F\xD6C\xEF%3\xCC!\xCAփ\x9C\x95N\xD8\xF7\u03A2\xD2\u0010\xEB\xBC~\xB2\u001Fy)\x9Ea\u0000\xE4@!\f\xD4\u0000\u0006\xB9\x82\u0006\xF3\xE07\x9B\xD5N؟\"\u001A0\xDE|\u0006\xF3z\xA9\xDB\u0013\xE4C\u0016\xD0\\b\xC5q,\xD2oM\xAC\u0000\u0000\u0011\xAAb\xDC#}\x9FV\xFB2\xEFC\x97\xD79\xD4\u001C#}\x9FV\xFB2\xEFC\x97\xD78gfn\xF1\xE3\xC8ͭ\xEB \u0000\u0000\x90\xA6c\u0015O\xAC\x9E\xDA(\x97\xAA\x9FY=\xB4Q\u0016u\xB7\x99\x98\xBE,ۗ\xD4@\u0000\u0005C\xD8\u001D/c\xF9\x9FD\xECmn9\xA0\xE9{\u001F\xCC\xFA'ckq\bs\u0560\xE7%S\xB6=\xF3\xA8\xB4eh9\xC9T\xED\x8F|\xEA-!\u0000\u0000\bC\xFF\xD9"
|
metadata
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ffi-gmagick
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Richard Hurt
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-11-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ffi
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.9'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.9'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.3'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: |-
|
56
|
+
This is not a simple 'Ruby'-like implementation. It is more of a
|
57
|
+
raw 'C' implementation. As such, it may be a bit more difficult to
|
58
|
+
work with than something like rmagick, but it should perform just as
|
59
|
+
well.
|
60
|
+
email:
|
61
|
+
- rnhurt@gmail.com
|
62
|
+
executables: []
|
63
|
+
extensions: []
|
64
|
+
extra_rdoc_files: []
|
65
|
+
files:
|
66
|
+
- .gitignore
|
67
|
+
- .travis.yml
|
68
|
+
- Gemfile
|
69
|
+
- LICENSE.txt
|
70
|
+
- README.md
|
71
|
+
- Rakefile
|
72
|
+
- ffi-gmagick.gemspec
|
73
|
+
- lib/ffi/gmagick.rb
|
74
|
+
- lib/ffi/gmagick/image.rb
|
75
|
+
- lib/ffi/gmagick/struct.rb
|
76
|
+
- lib/ffi/gmagick/version.rb
|
77
|
+
- test/image_test.rb
|
78
|
+
- test/test_helper.rb
|
79
|
+
homepage: https://github.com/rnhurt/ffi-gmagick
|
80
|
+
licenses:
|
81
|
+
- MIT
|
82
|
+
metadata: {}
|
83
|
+
post_install_message:
|
84
|
+
rdoc_options: []
|
85
|
+
require_paths:
|
86
|
+
- lib
|
87
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - '>='
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
requirements:
|
98
|
+
- libGraphicsMagick, v1.3.18
|
99
|
+
rubyforge_project:
|
100
|
+
rubygems_version: 2.1.11
|
101
|
+
signing_key:
|
102
|
+
specification_version: 4
|
103
|
+
summary: Use the C GraphicsMagick bindings to provide a Ruby interface
|
104
|
+
test_files:
|
105
|
+
- test/image_test.rb
|
106
|
+
- test/test_helper.rb
|