Skip to content

Instantly share code, notes, and snippets.

@DRBragg
Last active September 27, 2023 06:46
Show Gist options
  • Save DRBragg/bb52b7e6ee68c8401a5f7a076a8309a4 to your computer and use it in GitHub Desktop.
Save DRBragg/bb52b7e6ee68c8401a5f7a076a8309a4 to your computer and use it in GitHub Desktop.
PDF Previews with carrierwave
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
@NRavindra90
Copy link

Sorry for disterub you, I am new for rails so I am asking you. I am stuck in middle in my work.Is there possibility to use the active storage like any gems to create a thumbnail as first page of. ppt, pdf, doc, excel . Thanks

@DRBragg
Copy link
Author

DRBragg commented Dec 22, 2021

Yes, ActiveStorage has the ability to make previews of the first page of pdf's (and videos) and you can write your own previewer for other file types too

@NRavindra90
Copy link

I did it using poppler gem but no luck .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment