Carrierwave MiniMagick PDF Preview - carrierwave

Uploading files in my Rails app via Carrierwave / MiniMagick. Trying to create previews of the first page of PDFs. Ran into a few issues:
1) Some PDFs convert but the background is all black. Images and comments are visible
2) Some PDFs result in this error:
ImageProcessing::Error - Source format is multi-layer, but destination format is single-layer. If you care only about the first layer, add `.loader(page: 0)` to your pipeline. If you want to process each layer, see https://github.com/janko/image_processing/wiki/Splitting-a-PDF-into-multiple-images or use `.saver(allow_splitting: true)`.:
My codes looks like this:
version :thumb do
process :convert => 'jpg'
process :resize_to_limit => [50, 50]
def full_filename (for_file = model.file.file)
"preview_thumb.jpg"
end
end
Not clearly understanding which MiniMagick command line arg to add and how to add them.

Related

Carrierwave: convert an uploaded PNG to JPG by replacing the original version (or: having versions with a different file format than original file)

I have the following model:
class ScreenshotUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
storage :file
convert :jpg
version :thumb do
process resize_to_fill: [50, 50]
end
def extension_whitelist
%w(jpg jpeg gif png)
end
version :print do
process border: ['black']
process quality: 80
end
end
The upload of the image happens via pasting an image from the clipboard via https://github.com/layerssss/paste.js and is saved as a base64 encoded string into a <textarea>, then uploaded using the https://github.com/y9v/carrierwave-base64 gem:
class Finding < ApplicationRecord
mount_base64_uploader :screenshot, ScreenshotUploader
end
In the HTML form, it looks like this:
After uploading, the result is the following files:
screenshot.png it's a PNG, not a JPG!
thumb_screenshot.jpg
print_screenshot.jpg
But I need the original file to be also converted to JPG, as I need to save disk space. How can I achieve this?
You can do it like it written on the carrier wave documentation
Just replace system("mogrify -resize '1200\>' #{file.file}") with system("mogrify -format jpg #{file.file}") and then remove original file.
Adding to Vasiliy's answer, I came up with the following:
after :store, :convert_original_to_jpg
def convert_original_to_jpg(new_file)
if version_name.nil?
system("mogrify -format jpg -quality 80 #{file.file}")
system("unlink #{file.file}") # Remove the old PNG file
model.update_column mounted_as, "#{mounted_as}.jpg" # The filename in the DB also needs to be manually set to .jpg!
end
end
While this works for creating the file, it does not when updating the file, as the new_file parameter then is nil, and thus all images are removed.
I think this is some quirk that has to do with the carrierwave-base64 gem, and I don't have any motivation to dig into this any further. So the proposed solution might not be too useful, but for the sake of documentation I wanted to post it here.
In my special case, I decided to let go of the idea of saving disk space by converting PNG to JPG. Instead, I simply set process quality: 80 to save at least some space on the versions.
For the original PNG (which is saved in lossless state by carrierwave-base64 gem), I simply use the following code to shrink its quality:
after :store, :optimise_images
def optimise_images(new_file)
return if Rails.env.test? # Optimising consumes quite some time, so let's disable it for tests
if version_name.nil?
image_optim = ImageOptim.new pngout: false,
svgo: false,
pngcrush: false,
optipng: false,
pngquant: {allow_lossy: true}, # Everything disabled except pngquant, to keep the performance at a good level
advpng: false
image_optim.optimize_images!(Dir["#{File.dirname(file.file)}/*.png"])
end
end

How can I a create thumbnail for any files like (image, video, PDF, .xlsx, .ai, etc) using carrierwave in Rails 5

I've tried with
system("convert -strip -thumbnail '100x>' #{org_file.file}[0] #{thumb}.png")
but this is not working on Heroku..
Is there any way to create a thumbnail?
Thanks
You would need to define it in your uploader
#Create different versions of your uploaded files:
version :thumb do
process :resize_to_fit => [50, 50]
end
checkout this

How to place text on image

Is there a way to place text on image in Rails? I am using Carrierwave for image upload, but I don't think it supports watermarking.
I tried attaching image watermark and made it work but can't figure out how to watermark with text.
For example, this is good way to place image watermark.
This is the code that I user to put watermarks on a image I am sure that you can change it a bit to make it your own. Also make sure that you have Magick turned on.
Take a look at carrierwave-add-a-watermark-to-processed-images its similar
# Process files as they are uploaded:
process :resize_to_fill => [850, 315]
process :convert => 'png'
process :watermark
def watermark
manipulate! do |img|
logo = Magick::Image.read("#{Rails.root}/app/assets/images/watermark.png").first
img = img.composite(logo, Magick::NorthWestGravity, 15, 0, Magick::OverCompositeOp)
end
end

How to check if image version exists on S3 with Carrierwave and Fog?

I'm uploading my images with Carrierwave and Fog to S3. On the upload I also create a thumbnail version of the image:
version :thumb do
process :resize_to_limit => [90, 80], if: :is_resizable?
end
Now I need a method to check if thumbnail version exists.
The Documentation lists the exists? method. This actually works, if I want to check the existence of the original version:
asset.file.exists? # => true
But when I use the "thumb" version like this:
asset.url(:thumb).file.exists?
it get:
undefined method 'exists?' for #<String:0x007fcd9f9d9620>:
Use this:
asset.thumb.file.exists?
instead of: asset.url(:thumb).file.exists?
The correct answer is:
asset.file.thumb.file.exists?
where file = mounted_uploader and asset = model

FloatDomainError (Infinity)

I use carrierwave and mini_magick to upload images. In development everything is fine, but in production it raises FloatDomainError (Infinity) when i try to upload an image. I have several projects hosted at the same server and everything is fine with uploading.
I use Rails 3.0.10.
Any ideas how can i fix it? Thanks
I had the same problem. The problem is mini_magick. If the image file it runs identify on is erroneous, identify will output some kind of error, e.g.
identify: Corrupt JPEG data: 7929 extraneous bytes before marker 0xed `image.jpg' # warning/jpeg.c/EmitMessage/230.
11811 8665
mini_magick tries to parse the error message as the dimension, and the result is 0. This results in a division by zero which results in the exception you mentioned. This is the reason why it only fails with some images.
identify has a -quiet options to turn off these warning messages. I have forked mini_magick at https://github.com/fschwahn/mini_magick and added the quiet option. I hope this change will be pulled in (or the problem will be fixed in a more elegant way). However, for now you can use my fork by adding the following to your Gemfile:
gem 'mini_magick', :git => 'git://github.com/fschwahn/mini_magick.git'
Fixed that with replacing resize_and_fill to resize_and_pad. Still don't understand its strange behavior.
I was using the Ubuntu Imagemagick package version 6.7. I upgraded to 6.8 following the instructions here: https://askubuntu.com/questions/267746/how-can-i-install-the-latest-upstream-version-of-imagemagick-without-compiling and it worked.
I got this error with the newest gem update, when I generated an image thumbnail for my pdf file.
This code fails:
version :thumb do
process :resize_to_fill => [260, 192]
process :convert => :png
process :set_content_type
process :thumbnail_pdf
end
I solved it by replacing the order of the lines. The key was that before resizing MiniMagic should first convert thumbnail to image and after that should try to resize.
Here is solution which worked for me. Maybe it'll help for someone.
process :convert => :png
process :resize_to_fill => [260, 192]

Resources