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 |
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
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
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