prawn-gmagick 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 71345ece376bc00b760d62440468697d2505208f
4
+ data.tar.gz: a5dd71dd5675e504cb17775428d0e3a57d10d230
5
+ SHA512:
6
+ metadata.gz: 5d1c789b398543732e3ba20412f54a50615b21c75c56d623602e7de76eb2cedd606adb24840a00905e5392eb5fd4bd12929de7832720aab1b0965d9d9555d060
7
+ data.tar.gz: fe6abf387dd53d29af71aee61e8d82243345ebc40639c88b74015c28f9111d07ec3e43b17a7d3bda4581233daef721a33b74d382ad873b1bfd8bf8ed7d009caf
@@ -0,0 +1,34 @@
1
+ # prawn-gmagick
2
+
3
+ A [graphicsmagick](http:////www.graphicsmagick.org/) binding to add support for
4
+ additional image formats to [prawn](https://github.com/prawnpdf/prawn).
5
+
6
+ ## Usage
7
+
8
+ **Gemfile**
9
+
10
+ ```ruby
11
+ gem "prawn-gmagick"
12
+ ```
13
+
14
+ **Your code**
15
+
16
+ ```ruby
17
+ require "prawn-gmagick"
18
+ ```
19
+
20
+ ## Found a bug?
21
+ Open a [github issue](https://github.com/packetmonkey/prawn-gmagick/issues)
22
+
23
+ ## Contributing & Development
24
+ 1. Fork the project.
25
+ 2. Make your feature addition or bug fix. All specs should pass.
26
+ 3. Add specs for your changes.
27
+ 4. Commit
28
+ 5. Send a pull request. Bonus points for topic branches.
29
+
30
+ ## Licence
31
+ prawn-gmagick is released under the [MIT Licence](http://choosealicense.com/licenses/mit/)
32
+
33
+ ## Authors
34
+ prawn-gmagick is written and maintained by Evan Sharp.
@@ -0,0 +1,36 @@
1
+ $LOAD_PATH.unshift File.join(__dir__, "lib")
2
+
3
+ require "rake/testtask"
4
+ require "rake/extensiontask"
5
+
6
+ task "default" => :test
7
+
8
+ Rake::ExtensionTask.new "gmagick" do |ext|
9
+ ext.lib_dir = "lib/prawn-gmagick/gmagick"
10
+ end
11
+
12
+ Rake::TestTask.new do |t|
13
+ t.pattern = "test/**/*_test.rb"
14
+ end
15
+ task "test" => :compile
16
+
17
+ desc "Generate an example PDF using the images in test/fixtures"
18
+ task "example" do
19
+ $LOAD_PATH.unshift "./lib"
20
+ require "prawn-gmagick"
21
+ doc = Prawn::Document.new margin: 0
22
+ files = %w(rgb.gif rgb_alpha.gif rgb.jpg cmyk.jpg rgb.pdf rgb_alpha.pdf rgb.png rgb_alpha.png rgb.tiff rgb.bmp)
23
+ files.each do |filename|
24
+ start_time = Time.now
25
+ doc.start_new_page unless filename == files.first
26
+
27
+ doc.fill_color "00FF11"
28
+ doc.fill_rectangle [0, 11 * 72], 400, 400
29
+ doc.fill_color "000000"
30
+ file_path = File.join __dir__, "test", "fixtures", filename
31
+ doc.text file_path
32
+ doc.image file_path, height: 200
33
+ puts "Added #{file_path} in #{Time.now-start_time} seconds"
34
+ end
35
+ doc.render_file "example.pdf"
36
+ end
@@ -0,0 +1,4 @@
1
+ require "mkmf"
2
+
3
+ pkg_config("GraphicsMagickWand")
4
+ create_makefile("gmagick")
@@ -0,0 +1,150 @@
1
+ #include <ruby.h>
2
+ #include <string.h>
3
+ #include <wand/magick_wand.h>
4
+
5
+ VALUE format(VALUE self, VALUE rb_image_blob)
6
+ {
7
+ const char *format = NULL;
8
+ long double image_blob_length = RSTRING_LEN(rb_image_blob);
9
+ char *image_blob = RSTRING_PTR(rb_image_blob);
10
+
11
+ InitializeMagick(".");
12
+ MagickWand *magick_wand = NewMagickWand();
13
+ MagickReadImageBlob(magick_wand, (const unsigned char *)image_blob, image_blob_length);
14
+ format = MagickGetImageFormat(magick_wand);
15
+
16
+ if (format) {
17
+ return rb_str_new2(format);
18
+ } else {
19
+ return Qnil;
20
+ }
21
+ }
22
+
23
+ VALUE image_initialize(VALUE self, VALUE rb_image_blob)
24
+ {
25
+ MagickWand *magick_wand;
26
+
27
+ InitializeMagick(".");
28
+
29
+ magick_wand = NewMagickWand();
30
+
31
+ long double image_blob_length = RSTRING_LEN(rb_image_blob);
32
+ char *image_blob = RSTRING_PTR(rb_image_blob);
33
+ MagickReadImageBlob(magick_wand, (const unsigned char *)image_blob, image_blob_length);
34
+
35
+ VALUE rb_wand = Data_Wrap_Struct(rb_cObject, NULL, NULL, magick_wand);
36
+
37
+ rb_funcall(self, rb_intern("wand="), 1, rb_wand);
38
+ rb_funcall(self, rb_intern("blob="), 1, rb_image_blob);
39
+
40
+ return Qtrue;
41
+ }
42
+
43
+ VALUE image_depth(VALUE self)
44
+ {
45
+ VALUE rb_wand = rb_funcall(self, rb_intern("wand"), 0);
46
+ MagickWand *magick_wand;
47
+ Data_Get_Struct(rb_wand, MagickWand, magick_wand);
48
+
49
+ unsigned long depth = MagickGetImageChannelDepth(magick_wand, RedChannel);
50
+ return INT2NUM(depth);
51
+ }
52
+
53
+ VALUE image_width(VALUE self)
54
+ {
55
+ VALUE rb_wand = rb_funcall(self, rb_intern("wand"), 0);
56
+ MagickWand *magick_wand;
57
+ Data_Get_Struct(rb_wand, MagickWand, magick_wand);
58
+ unsigned long width = MagickGetImageWidth(magick_wand);
59
+ return INT2NUM(width);
60
+ }
61
+
62
+ VALUE image_height(VALUE self)
63
+ {
64
+ VALUE rb_wand = rb_funcall(self, rb_intern("wand"), 0);
65
+ MagickWand *magick_wand;
66
+ Data_Get_Struct(rb_wand, MagickWand, magick_wand);
67
+ unsigned long height = MagickGetImageHeight(magick_wand);
68
+ return INT2NUM(height);
69
+ }
70
+
71
+ VALUE image_colorspace(VALUE self)
72
+ {
73
+ VALUE rb_wand = rb_funcall(self, rb_intern("wand"), 0);
74
+ MagickWand *magick_wand;
75
+ Data_Get_Struct(rb_wand, MagickWand, magick_wand);
76
+ ColorspaceType color_space = MagickGetImageColorspace(magick_wand);
77
+ if (color_space == RGBColorspace) {
78
+ return ID2SYM(rb_intern("DeviceRGB"));
79
+ } else if (color_space == CMYKColorspace) {
80
+ return ID2SYM(rb_intern("DeviceCMYK"));
81
+ } else {
82
+ rb_raise(rb_eTypeError, "Unknown colorspace");
83
+ }
84
+ }
85
+
86
+ VALUE image_unpack(VALUE self)
87
+ {
88
+ VALUE rb_wand = rb_funcall(self, rb_intern("wand"), 0);
89
+ MagickWand *magick_wand;
90
+ Data_Get_Struct(rb_wand, MagickWand, magick_wand);
91
+ ColorspaceType color_space = MagickGetImageColorspace(magick_wand);
92
+
93
+ int height = NUM2INT( rb_funcall(self, rb_intern("height"), 0) );
94
+ int width = NUM2INT( rb_funcall(self, rb_intern("width"), 0) );
95
+ int pixel_count = height * width;
96
+ int buffer_size;
97
+ char color_format[8];
98
+ unsigned char *pixels;
99
+
100
+ if (color_space == RGBColorspace) {
101
+ buffer_size = 3 * pixel_count;
102
+ strcpy(color_format, "RGB");
103
+ } else if (color_space == CMYKColorspace) {
104
+ buffer_size = 4 * pixel_count;
105
+ strcpy(color_format, "CMYK");
106
+ } else {
107
+ rb_raise(rb_eTypeError, "Unknown colorspace");
108
+ }
109
+
110
+ pixels = (unsigned char *)malloc(buffer_size * sizeof(char));
111
+ MagickGetImagePixels(magick_wand, 0, 0, width, height, color_format, CharPixel, pixels);
112
+
113
+ return rb_str_new((const char *)pixels, buffer_size);
114
+ }
115
+
116
+ VALUE image_alpha_unpack(VALUE self)
117
+ {
118
+ VALUE rb_wand = rb_funcall(self, rb_intern("wand"), 0);
119
+ MagickWand *magick_wand;
120
+ Data_Get_Struct(rb_wand, MagickWand, magick_wand);
121
+ int height = NUM2INT( rb_funcall(self, rb_intern("height"), 0) );
122
+ int width = NUM2INT( rb_funcall(self, rb_intern("width"), 0) );
123
+ int pixel_count = height * width;
124
+ unsigned char *pixels;
125
+
126
+ pixels = (unsigned char *)malloc(pixel_count * sizeof(char));
127
+ MagickGetImagePixels(magick_wand, 0, 0, width, height, "A", CharPixel, pixels);
128
+ return rb_str_new((const char *)pixels, pixel_count);
129
+ }
130
+
131
+ void Init_gmagick(void)
132
+ {
133
+ // Deine our name spaces and classes
134
+ VALUE m_gmagick = rb_define_module("GMagick");
135
+ VALUE c_image = rb_define_class_under(m_gmagick, "Image", rb_cObject);
136
+
137
+ // Define our class methods
138
+ rb_define_singleton_method(c_image, "format", format, 1);
139
+
140
+ // Define our instance methods
141
+ rb_define_attr(c_image, "blob", 1, 1);
142
+ rb_define_attr(c_image, "wand", 1, 1);
143
+ rb_define_method(c_image, "initialize", image_initialize, 1);
144
+ rb_define_method(c_image, "depth", image_depth, 0);
145
+ rb_define_method(c_image, "width", image_width, 0);
146
+ rb_define_method(c_image, "height", image_height, 0);
147
+ rb_define_method(c_image, "colorspace", image_colorspace, 0);
148
+ rb_define_method(c_image, "unpack", image_unpack, 0);
149
+ rb_define_method(c_image, "alpha_unpack", image_alpha_unpack, 0);
150
+ }
@@ -0,0 +1,52 @@
1
+ require "prawn-gmagick/gmagick/gmagick"
2
+
3
+ require "prawn"
4
+
5
+ class Gmagick < Prawn::Images::Image
6
+ attr_reader :width, :height, :bits, :channels
7
+ attr_accessor :scaled_width, :scaled_height
8
+ attr_accessor :gimage
9
+
10
+ def self.can_render? image_blob
11
+ GMagick::Image.format(image_blob) ? true : false
12
+ end
13
+
14
+ def initialize image_blob
15
+ self.gimage = GMagick::Image.new image_blob
16
+
17
+ @bits = self.gimage.depth
18
+ @width = self.gimage.width
19
+ @height = self.gimage.height
20
+ end
21
+
22
+ def build_pdf_object(document)
23
+ obj = document.ref!(
24
+ Type: :XObject,
25
+ Subtype: :Image,
26
+ ColorSpace: gimage.colorspace,
27
+ Height: @height,
28
+ Width: @width,
29
+ BitsPerComponent: @bits
30
+ )
31
+ obj << gimage.unpack
32
+
33
+ alpha_mask = self.gimage.alpha_unpack
34
+ if alpha_mask.unpack("C*").uniq.length > 1
35
+ smask_obj = document.ref!(
36
+ :Type => :XObject,
37
+ :Subtype => :Image,
38
+ :Height => gimage.height,
39
+ :Width => gimage.width,
40
+ :BitsPerComponent => gimage.depth,
41
+ :ColorSpace => :DeviceGray,
42
+ :Decode => [0, 1]
43
+ )
44
+ smask_obj.stream << alpha_mask
45
+ obj.data[:SMask] = smask_obj
46
+ end
47
+
48
+ obj
49
+ end
50
+ end
51
+
52
+ Prawn.image_handler.register! Gmagick
@@ -0,0 +1,12 @@
1
+ ___,,___
2
+ _,-='=- =- -`"--.__,,.._
3
+ ,-;// / - - - -= - "=.
4
+ ,'/// - - - = - ==-=\`.
5
+ |/// / = `. - = == - =.=_,,._ `=/|
6
+ /// - - \ - - = ,ndDMHHMM/\b \\
7
+ ,' - / / / /\ = - /MM(,,._`YQMML `|
8
+ <_,=^Kkm / / / / ///H|wnWWdMKKK#""-;. `"0\ |
9
+ `""QkmmmmmnWMMM\""WHMKKMM\ `--. \> \
10
+ hjm `""' `->>> ``WHMb,. `-_<@)
11
+ `"QMM`.
12
+ `>>>
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,111 @@
1
+ require_relative "../test_helper"
2
+
3
+ describe "GMagick::Image::format" do
4
+ describe "with a JPEG image" do
5
+ before do
6
+ fixture_path = File.join __dir__, "..", "fixtures", "rgb.jpg"
7
+ @fixture_blob = File.open(fixture_path).read
8
+ end
9
+
10
+ it "returns a string containing 'JPEG'" do
11
+ GMagick::Image.format(@fixture_blob).must_equal "JPEG"
12
+ end
13
+ end
14
+
15
+ describe "with an unknown image" do
16
+ before do
17
+ fixture_path = File.join __dir__, "..", "fixtures", "random.bin"
18
+ @fixture_blob = File.open(fixture_path).read
19
+ end
20
+
21
+ it "returns nil" do
22
+ GMagick::Image.format(@fixture_blob).must_equal nil
23
+ end
24
+ end
25
+ end
26
+
27
+ describe GMagick::Image do
28
+ before do
29
+ fixture_path = File.join __dir__, "..", "fixtures", "rgb.jpg"
30
+ fixture_blob = File.open(fixture_path).read
31
+ @image = GMagick::Image.new fixture_blob
32
+ end
33
+
34
+ describe "#depth" do
35
+ it "returns the image bit depth as an integer" do
36
+ @image.depth.must_equal 8
37
+ end
38
+ end
39
+
40
+ describe "#width" do
41
+ it "returns the image width in pixels as an integer" do
42
+ @image.width.must_equal 13
43
+ end
44
+ end
45
+
46
+ describe "#height" do
47
+ it "returns the image height in pixels as an integer" do
48
+ @image.height.must_equal 17
49
+ end
50
+ end
51
+
52
+ describe "#colorspace" do
53
+ describe "with an RGB image" do
54
+ it "returns the symbol :DeviceRGB" do
55
+ @image.colorspace.must_equal :DeviceRGB
56
+ end
57
+ end
58
+
59
+ describe "with a CMYK image" do
60
+ before do
61
+ fixture_path = File.join __dir__, "..", "fixtures", "cmyk.jpg"
62
+ fixture_blob = File.open(fixture_path).read
63
+ @image = GMagick::Image.new fixture_blob
64
+ end
65
+
66
+ it "returns the symbol :DeviceCMYK" do
67
+ @image.colorspace.must_equal :DeviceCMYK
68
+ end
69
+ end
70
+ end
71
+
72
+ describe "#unpack" do
73
+ describe "with an RGB image" do
74
+ it "returns a string containing the pixel color information" do
75
+ @image.unpack.unpack("CCC").must_equal [255, 38, 0]
76
+ end
77
+ end
78
+
79
+ describe "with a CMYK image" do
80
+ before do
81
+ fixture_path = File.join __dir__, "..", "fixtures", "cmyk.jpg"
82
+ fixture_blob = File.open(fixture_path).read
83
+ @image = GMagick::Image.new fixture_blob
84
+ end
85
+
86
+ it "returns a string containing the pixel color information" do
87
+ @image.unpack.unpack("CCCC").must_equal [55, 27, 0, 0]
88
+ end
89
+ end
90
+ end
91
+
92
+ describe "#unpack_alpha" do
93
+ describe "with an opaque JPEG" do
94
+ it "returns a string containing the pixel alpha information" do
95
+ @image.alpha_unpack.unpack("CCCC").must_equal [255, 255, 255, 255]
96
+ end
97
+ end
98
+
99
+ describe "with an transparent GIF" do
100
+ before do
101
+ fixture_path = File.join __dir__, "..", "fixtures", "rgb_alpha.gif"
102
+ fixture_blob = File.open(fixture_path).read
103
+ @image = GMagick::Image.new fixture_blob
104
+ end
105
+
106
+ it "returns a string containing the pixel alpha information" do
107
+ @image.alpha_unpack.unpack("C*").slice(11, 3).must_equal [255, 255, 0]
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,6 @@
1
+
2
+ require "minitest/autorun"
3
+ require "minitest/pride"
4
+ require "minitest/hell"
5
+
6
+ require "prawn-gmagick"
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: prawn-gmagick
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Evan Sharp
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-12-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: prawn
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 0.13.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 0.13.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake-compiler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
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: minitest
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
+ email:
57
+ executables: []
58
+ extensions:
59
+ - ext/gmagick/extconf.rb
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ext/gmagick/extconf.rb
63
+ - ext/gmagick/gmagick.c
64
+ - lib/prawn-gmagick/gmagick/gmagick.bundle
65
+ - lib/prawn-gmagick.rb
66
+ - test/fixtures/ascii.txt
67
+ - test/fixtures/cmyk.jpg
68
+ - test/fixtures/random.bin
69
+ - test/fixtures/rgb.bmp
70
+ - test/fixtures/rgb.gif
71
+ - test/fixtures/rgb.jpg
72
+ - test/fixtures/rgb.pdf
73
+ - test/fixtures/rgb.png
74
+ - test/fixtures/rgb.tiff
75
+ - test/fixtures/rgb_alpha.gif
76
+ - test/fixtures/rgb_alpha.pdf
77
+ - test/fixtures/rgb_alpha.png
78
+ - test/gmagick/image_test.rb
79
+ - test/test_helper.rb
80
+ - README.markdown
81
+ - Rakefile
82
+ homepage:
83
+ licenses:
84
+ - MIT
85
+ metadata: {}
86
+ post_install_message:
87
+ rdoc_options: []
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - '>='
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ requirements: []
101
+ rubyforge_project:
102
+ rubygems_version: 2.0.3
103
+ signing_key:
104
+ specification_version: 4
105
+ summary: Use GraphicsMagick to load images in a Prawn docuemnt
106
+ test_files: []