Patching paperclip to create thumbnails only for images
August 1st, 2008
Paperclip has some good features over attachment_fu that "attached files don’t need to have a seperare model (thank god). Your attachments are treated just like any other atribute. Images aren’t saved until your model is saved" ( by Jim Neath ).
The fall back of paperclip is that it tries to create a thumbnail for any type of file, including pdf. It won't cause much problem if it cannot create a thumbnail to a certain file. But when it comes to pdf file, paperclip tries to generate a thumbnail for every page of the file, it becomes very slow when uploading the pdf file if the file has hundreds of pages. Sometimes it even times out! At the same time, attachment_fu does not have this problem.
attachment_fu.rb includes a class method #images? to distinguish if the file is an image.
1 2 3 4 |
129 # Returns true or false if the given content type is recognized as an image. 130 def image?(content_type) 131 content_types.include?(content_type) 132 end |
Content types of images are initialized at the begin of the file:
5 @@content_types = ['image/jpeg', 'image/pjpeg', 'image/gif', 'image/png', 'image/x-png', 'image/jpg'] |
Then the #image? method is called in a instantial method #thumbnailable:
1 2 3 4 5 6 7 8 9 10 |
216 # Checks whether the attachment's content type is an image content type
217 def image?
218 self.class.image?(content_type)
219 end
220
221 # Returns true/false if an attachment is thumbnailable.
# A thumbnailable attachment has an image content type and the parent_id attribute.
222 def thumbnailable?
223 image? && respond_to?(:parent_id) && parent_id.nil?
224 end |
In the #create_or_update_thumbnail it test if the content is thumbnailable? to determine going or not.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
243 # Creates or updates the thumbnail for the current attachment. 244 def create_or_update_thumbnail(temp_file, file_name_suffix, *size) 245 thumbnailable? || raise(ThumbnailError.new("Can't create a thumbnail if the content \ type is not an image or there is no parent_id column")) 246 returning find_or_initialize_thumbnail(file_name_suffix) do |thumb| 247 thumb.attributes = { 248 :content_type => content_type, 249 :filename => thumbnail_name_for(file_name_suffix), 250 :temp_path => temp_file, 251 :thumbnail_resize_options => size 252 } 253 callback_with_args :before_thumbnail_saved, thumb 254 thumb.save! 255 end 256 end |
Paperclip has a similar structure like this, it makes it easier to make this patch.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
From line #217 def post_process #:nodoc: return if @queued_for_write[:original].nil? logger.info("[paperclip] Post-processing #{name}") @styles.each do |name, args| begin dimensions, format = args dimensions = dimensions.call(instance) if dimensions.respond_to? :call @queued_for_write[name] = Thumbnail.make(@queued_for_write[:original], dimensions, format, @whiny_thumnails) rescue PaperclipError => e @errors << e.message if @whiny_thumbnails end end end |
The trick here is to add the #thumbnailable? method in right after the #begin keyword and raise a PaperclipError if it fails:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
213 def post_process #:nodoc: 214 return if @queued_for_write[:original].nil? 215 @styles.each do |name, args| 216 begin # Test here 217 thumbnailable? || raise(PaperclipError.new("Can not create thumbnails \ if the content type is not an image.")) 218 dimensions, format = args 219 dimensions = dimensions.call(instance) if dimensions.respond_to? :call 220 @queued_for_write[name] = Thumbnail.make(@queued_for_write[:original],- 221 dimensions, 222 format,- 223 @whiny_thumnails) 224 rescue PaperclipError => e 225 @errors << e.message if @whiny_thumbnails 226 end 227 end 228 end |
Add the #image? and #thumbnailable? method to attachment.rb of paperclip, and initialize the thumbnailable content types at the beginning. That's all, now you can upload pdf files very fast.
About how to use paperclip, Jim Neath has a great tutorial Paperclip: Attaching Files in Rails. Enjoy it!
1 Response to “Patching paperclip to create thumbnails only for images”
Sorry, comments are closed for this article.

August 22nd, 2008 at 01:41 PM paperclip is awesome! I have write a crop patch for it.