Namespace

Prawn::Images

Public Instance Methods

image(file, options={}) click to toggle source

Add the image at filename to the current page. Currently only JPG and PNG files are supported.

NOTE: Prawn is very slow at rendering PNGs with alpha channels. The workaround for those who don’t mind installing RMagick is to use:

github.com/amberbit/prawn-fast-png

Arguments:

file

path to file or an object that responds to #

Options:

:at

an array [x,y] with the location of the top left corner of the image.

:position

One of (:left, :center, :right) or an x-offset

:vposition

One of (:top, :center, :center) or an y-offset

:height

the height of the image [actual height of the image]

:width

the width of the image [actual width of the image]

:scale

scale the dimensions of the image proportionally

:fit

scale the dimensions of the image proportionally to fit inside [width,height]

  Prawn::Document.generate("image2.pdf", :page_layout => :landscape) do     
    pigs = "#{Prawn::BASEDIR}/data/images/pigs.jpg" 
    image pigs, :at => [50,450], :width => 450                                      

    dice = "#{Prawn::BASEDIR}/data/images/dice.png"
    image dice, :at => [50, 450], :scale => 0.75 
  end   

If only one of :width / :height are provided, the image will be scaled proportionally. When both are provided, the image will be stretched to fit the dimensions without maintaining the aspect ratio.

If :at is provided, the image will be place in the current page but the text position will not be changed.

If instead of an explicit filename, an object with a read method is passed as file, you can embed images from IO objects and things that act like them (including Tempfiles and open-uri objects).

  require "open-uri"

  Prawn::Document.generate("remote_images.pdf") do 
    image open("http://prawn.majesticseacreature.com/media/prawn_logo.png")
  end

This method returns an image info object which can be used to check the dimensions of an image object if needed. (See also: Prawn::Images::PNG , Prawn::Images::JPG)

     # File lib/prawn/images.rb, line 65
 65:     def image(file, options={})
 66:       Prawn.verify_options [:at, :position, :vposition, :height, 
 67:                             :width, :scale, :fit], options
 68: 
 69:       if file.respond_to?(:read)
 70:         image_content = file.read
 71:       else
 72:         raise ArgumentError, "#{file} not found" unless File.file?(file)  
 73:         image_content = File.binread(file)
 74:       end
 75:       
 76:       image_sha1 = Digest::SHA1.hexdigest(image_content)
 77: 
 78:       # if this image has already been embedded, just reuse it
 79:       if image_registry[image_sha1]
 80:         info = image_registry[image_sha1][:info]
 81:         image_obj = image_registry[image_sha1][:obj]
 82:       else
 83:         # Build the image object
 84:         klass = case detect_image_format(image_content)
 85:                 when :jpg then Prawn::Images::JPG
 86:                 when :png then Prawn::Images::PNG
 87:                 end
 88:         info = klass.new(image_content)
 89: 
 90:         # Bump PDF version if the image requires it
 91:         min_version(info.min_pdf_version) if info.respond_to?(:min_pdf_version)
 92: 
 93:         # Add the image to the PDF and register it in case we see it again.
 94:         image_obj = info.build_pdf_object(self)
 95:         image_registry[image_sha1] = {:obj => image_obj, :info => info}
 96:       end
 97: 
 98:       # find where the image will be placed and how big it will be  
 99:       w,h = calc_image_dimensions(info, options)
100: 
101:       if options[:at]     
102:         x,y = map_to_absolute(options[:at]) 
103:       else                  
104:         x,y = image_position(w,h,options) 
105:         move_text_position h   
106:       end
107: 
108:       # add a reference to the image object to the current page
109:       # resource list and give it a label
110:       label = "I#{next_image_id}"
111:       state.page.xobjects.merge!( label => image_obj )
112: 
113:       # add the image to the current page
114:       instruct = "\nq\n%.3f 0 0 %.3f %.3f %.3f cm\n/%s Do\nQ"
115:       add_content instruct % [ w, h, x, y - h, label ]
116:       
117:       return info
118:     end

Private Instance Methods

calc_image_dimensions(info, options) click to toggle source
     # File lib/prawn/images.rb, line 164
164:     def calc_image_dimensions(info, options)
165:       w = options[:width] || info.width
166:       h = options[:height] || info.height
167: 
168:       if options[:width] && !options[:height]
169:         wp = w / info.width.to_f 
170:         w = info.width * wp
171:         h = info.height * wp
172:       elsif options[:height] && !options[:width]         
173:         hp = h / info.height.to_f
174:         w = info.width * hp
175:         h = info.height * hp   
176:       elsif options[:scale] 
177:         w = info.width * options[:scale]
178:         h = info.height * options[:scale]
179:       elsif options[:fit] 
180:         bw, bh = options[:fit]
181:         bp = bw / bh.to_f
182:         ip = info.width / info.height.to_f
183:         if ip > bp
184:           w = bw
185:           h = bw / ip
186:         else
187:           h = bh
188:           w = bh * ip
189:         end
190:       end
191:       info.scaled_width = w
192:       info.scaled_height = h
193:       [w,h]
194:     end
detect_image_format(content) click to toggle source
     # File lib/prawn/images.rb, line 196
196:     def detect_image_format(content)
197:       top = content[0,128]                       
198: 
199:       # Unpack before comparing for JPG header, so as to avoid having to worry
200:       # about the source string encoding. We just want a byte-by-byte compare.
201:       if top[0, 3].unpack("C*") == [255, 216, 255]
202:         return :jpg
203:       elsif top[0, 8].unpack("C*") == [137, 80, 78, 71, 13, 10, 26, 10]
204:         return :png
205:       else
206:         raise Errors::UnsupportedImageType, "image file is an unrecognised format"
207:       end
208:     end
determine_y_with_page_flow(h) click to toggle source
     # File lib/prawn/images.rb, line 151
151:     def determine_y_with_page_flow(h)
152:       if overruns_page?(h)
153:         start_new_page
154:         bounds.absolute_top 
155:       else
156:         self.y
157:       end
158:     end
image_position(w,h,options) click to toggle source
     # File lib/prawn/images.rb, line 122
122:     def image_position(w,h,options)
123:       options[:position] ||= :left
124:       
125:       x = case options[:position] 
126:       when :left
127:         bounds.absolute_left
128:       when :center
129:         bounds.absolute_left + (bounds.width - w) / 2.0 
130:       when :right
131:         bounds.absolute_right - w
132:       when Numeric
133:         options[:position] + bounds.absolute_left
134:       end
135: 
136:       y = case options[:vposition]
137:       when :top
138:         bounds.absolute_top
139:       when :center
140:         bounds.absolute_top - (bounds.height - h) / 2.0
141:       when :bottom
142:         bounds.absolute_bottom + h
143:       when Numeric
144:         bounds.absolute_top - options[:vposition]
145:       else
146:         determine_y_with_page_flow(h)
147:       end
148:       return [x,y]
149:     end
image_registry() click to toggle source
     # File lib/prawn/images.rb, line 210
210:     def image_registry
211:       @image_registry ||= {}
212:     end
next_image_id() click to toggle source
     # File lib/prawn/images.rb, line 214
214:     def next_image_id
215:       @image_counter ||= 0
216:       @image_counter += 1
217:     end
overruns_page?(h) click to toggle source
     # File lib/prawn/images.rb, line 160
160:     def overruns_page?(h)
161:       (self.y - h) < bounds.absolute_bottom 
162:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.