I am pulling my hair out and have been searching for a solution for days. I am trying to take an uploaded pdf document and create a thumbnail that is viewable on all browsers. I can get it to work on Safari/iOS or Firefox/IE7+/Chrome but not one version that works everywhere. I've tried setting the colorspace to rgb(no effect), converting to png instead of jpg(no effect) and setting :set_content_type(no effect). I am getting the same result on my local machine and on production(Heroku).
pdfdoc_uploader.rb
include ImageManipulators
include CarrierWave::RMagick
include CarrierWave::MimeTypes
version :thumb do
process :convert => 'jpg' #<---This works in Safari and iOS
process :resize_to_fit => [200, 200]
process :paper_shape
process :strip
process :convert => 'jpg' #<---Move it here and it works everywhere else
def full_filename (for_file = model.logo.file)
super.chomp(File.extname(super)) + '.jpg'
end
end
image_manipulators.rb
module ImageManipulators
# creates an image with a 3x4 aspect ratio
def paper_shape
manipulate! do |img|
if img.rows*4 != img.columns*3
width=img.columns
height=img.columns/3*4
img.crop!(0,0,width,height,true)
else
img
end
end
end
def set_content_type(*args)
self.file.instance_variable_set(:@content_type, "image/jpeg")
end
# Autoorients image according to exif
def auto_orient
manipulate! {|img| img.auto_orient! || img }
end
# Crops the biggest possible square from the image
def biggest_square
manipulate! do |img|
if img.rows != img.columns
max = img.rows > img.columns ? img.columns : img.rows
img.crop!(0,0,max,max,true)
else
img
end
end
end
def paper_shape
manipulate! do |img|
if img.rows*4 != img.columns*3
width=img.columns
height=img.columns/3*4
img.crop!(0,0,width,height,true)
else
img
end
end
end
# Create rounded corners for the image
def rounded_corners
radius = 10
manipulate! do |img|
#create a masq of same size
masq = Magick::Image.new(img.columns, img.rows)
d = Magick::Draw.new
d.roundrectangle(0, 0, img.columns - 1, img.rows - 1, radius, radius)
d.draw(masq)
img.composite(masq, 0, 0, Magick::LightenCompositeOp)
end
end
# Rotates the image based on the EXIF Orientation
def fix_exif_rotation
manipulate! do |img|
img.auto_orient!
img = yield(img) if block_given?
img
end
end
# Strips out all embedded information from the image
def strip
manipulate! do |img|
img.strip!
img = yield(img) if block_given?
img
end
end
def colorspace(cs)
manipulate! do |img|
case cs
when 'rgb'
img.colorspace = Magick::RGBColorspace
when 'cmyk'
img.colorspace = Magick::CMYKColorspace
end
img = yield(img) if block_given?
img
end
end
end
I eventually gave up and just created two versions and used useragent to determine which one to display. While not an attractive option it is working. I hope someone comes up with a better solution.
version :thumb_safari do #special version for safari and ios
process :resize_to_fit => [200,200]
process :convert => 'jpg'
process :paper_shape
def full_filename (for_file = model.logo.file)
super.chomp(File.extname(super)) + '.jpg'
end
end
version :thumb do #all browsers except safari
process :resize_to_fit => [200,200]
process :convert => 'jpg' #must convert to jpg before running paper shape
process :paper_shape
process :convert => 'jpg' #after running paper_shape it will default to original file type
def full_filename (for_file = model.logo.file)
super.chomp(File.extname(super)) + '.jpg'
end
end
def paper_shape
manipulate! do |img|
if img.rows*4 != img.columns*3
width=img.columns
height=img.columns/3*4
img.crop!(0,0,width,height,true)
else
img
end
end
end
In the controller/view I used the useragent gem and did this:
documents_controller.rb
def index
@user_agent=UserAgent.parse(request.user_agent)
@search = Document.search(params[:q])
end
index.html.rb
<% if @user_agent.browser.downcase == 'safari' %>
<%= link_to(image_tag(doc.pdfdoc_url(:thumb_safari).to_s, :class=>"dropshadow", :size => "150x225"), doc.pdfdoc_url)%>
<% else %>
<%= link_to(image_tag(doc.pdfdoc_url(:thumb).to_s, :class=>"dropshadow", :size => "150x225"), doc.pdfdoc_url)%>
<% end %>
No doubt there is a better way to do this but this is working for now.