Created
February 11, 2014 15:14
-
-
Save willkoehler/8936717 to your computer and use it in GitHub Desktop.
Carrier uploader for documents that creates thumbnails from images and PDFs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class DocumentUploader < CarrierWave::Uploader::Base | |
include CarrierWave::RMagick | |
# Store on Amazon S3 using Fog | |
storage :fog | |
# Directory where uploaded files will be stored. | |
def store_dir | |
"documents/#{model.id}" | |
end | |
# Set the mime type (will be based on the file extension, which is more accurate than what's in the request header) | |
include CarrierWave::MimeTypes | |
process :set_content_type | |
# Create thumbnail for images and PDFs | |
version :thumb, :if => :thumbable? do | |
process :resize_to_fit => [240, 240], :if => :image? | |
process :pdf_preview => [240, 240], :if => :pdf? | |
process :get_geometry | |
def geometry | |
@geometry | |
end | |
# We need to change the extension for PDF thumbnails to '.jpg' | |
def full_filename(filename) | |
filename = File.replace_extension(filename, '.jpg') if File.extname(filename)=='.pdf' | |
"thumb_#{filename}" | |
end | |
end | |
def pdf_preview(width, height) | |
# Most PDFs have a transparent background, which becomes black when converted to jpg. | |
# To override this, we must create a white canvas and composite the PDF onto the convas. | |
# Read in first page of PDF and resize ([0] -> read the first page only) | |
image = ::Magick::Image.read("#{current_path}[0]").first | |
image.resize_to_fit!(width, height) | |
# Create a blank canvas | |
canvas = ::Magick::Image.new(image.columns, image.rows) { self.background_color = "#FFF" } | |
# Merge PDF thumbnail onto canvas | |
canvas.composite!(image, ::Magick::CenterGravity, ::Magick::OverCompositeOp) | |
# Save as .jpg. We need to change the file extension here so that the fog gem picks it up and | |
# sets the correct mime type. Otherwise the mime type will be set to PDF, which confuses browsers. | |
canvas.write("jpg:#{current_path}") | |
file.move_to File.replace_extension(current_path, '.jpg') | |
# Free memory allocated by RMagick which isn't managed by Ruby | |
image.destroy! | |
canvas.destroy! | |
rescue ::Magick::ImageMagickError => e | |
Rails.logger.error "Failed to create PDF thumbnail: #{e.message}" | |
raise CarrierWave::ProcessingError, "is not a valid PDF file" | |
end | |
# Extensions which are allowed to be uploaded. | |
def extension_white_list | |
%w(jpg jpeg gif png pdf doc docx txt mp3 xls xlsx) | |
end | |
private | |
def thumbable?(file) | |
image?(file) || pdf?(file) | |
end | |
def image?(file) | |
# Check the model first (see https://github.com/carrierwaveuploader/carrierwave/issues/1315) | |
return model.is_image? if model.content_type.present? | |
file.content_type.include? 'image' | |
end | |
def pdf?(file) | |
# Check the model first (see https://github.com/carrierwaveuploader/carrierwave/issues/1315) | |
return model.is_pdf? if model.content_type.present? | |
file.content_type == 'application/pdf' | |
end | |
def get_geometry | |
if (@file) | |
img = ::Magick::Image::read(@file.file).first | |
@geometry = { :width => img.columns, :height => img.rows } | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment