Last active
September 27, 2023 06:46
-
-
Save DRBragg/bb52b7e6ee68c8401a5f7a076a8309a4 to your computer and use it in GitHub Desktop.
PDF Previews with carrierwave
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 ItemUploader < CarrierWave::Uploader::Base | |
require 'carrierwave/orm/activerecord' | |
include CarrierWave::RMagick | |
attr_reader :geometry | |
# 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 | |
# handles cases where fog misses the content type | |
process :set_content_type | |
# We need to change the extension for PDF thumbnails to '.jpg' | |
def full_filename(filename) | |
filename = File.basename(filename, '.pdf') + '.jpg' if File.extname(filename)=='.pdf' | |
"thumb_#{filename}" | |
end | |
end | |
def pdf_preview(width, height) | |
# 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_fill!(width, height, ::Magick::NorthGravity) | |
# 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. | |
# First check the image backgrounf color. | |
# #FFFFFFFFFFFF0000 is how ImageMagick defines transparent | |
if image.background_color != "#FFFFFFFFFFFF0000" | |
# 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}") | |
else | |
# If the imag ebackground color is transparent we don't need to worry about the canvas. | |
image.write("jpg:#{current_path}") | |
end | |
file.move_to File.basename(filename, '.pdf') + '.jpg' | |
# Free memory allocated by RMagick which isn't managed by Ruby | |
image.destroy! | |
canvas.destroy! unless canvas.nil? | |
rescue ::Magick::ImageMagickError => e | |
Rails.logger.error "Failed to create PDF thumbnail: #{e.message}" | |
raise CarrierWave::ProcessingError, "is not a valid PDF file" | |
end | |
def set_content_type(*args) | |
self.file.instance_variable_set(:@content_type, "image/jpeg") | |
end | |
private | |
def thumbable?(file) | |
image?(file) || pdf?(file) | |
end | |
def image?(file) | |
file.content_type.include? 'image' | |
end | |
def pdf?(file) | |
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
I did it using poppler gem but no luck .