I am using the carrierwave gem with Rmagick in a Rails app. I've set up a new version in my uploader file:
class ImageUploader < CarrierWave::Uploader::Base
include CarrierWave::RMagick
storage :file
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
version :preview do
process :resize_to_fill => [580, 350]
end
end
Of course, I included rmagick and carrierwave in my gemfile. Now I try to load the preview version of my images in my views:
#product.photos.first.image.preview
This does not give any errors, but loads a broken image. If I copy the url of the image, I get a routing error ('no route matches /path/to_my_imagesfolder/preview_image.png'). If I remove the preview method, the image loads properly.
What can the problem be? I thought maybe it was a permissions issue, but I set the uploads folder with 777 and it still fails.
Any ideas?
EDIT: I realized if I upload the images again the new versions are created. Is it possible to make Rmagick create them when they are requested (like TimThumb does in PHP) Or at least is there any command to batch create all the versions?
There must be a better way than uploading all the images...
You can use .recreate_versions!
For example:
Product.all.each do |product|
product.photos.each do |photo|
photo.recreate_versions!
end
end
I'd just use this: https://github.com/markevans/dragonfly
Related
Love carrierwave.
When running the recreate_version! the quality of ORIGINAL image is dramatically reduced/corrupted.
I need to use carrierwave's recreate_version! to add a new "mobile" version to an existing Photo model via the mount_uploader :image.
Existing version: original, :card and :thumb
Again, when running the recreate_version! the quality of ORIGINAL image is dramatically reduced.
Mayor image corruption of the original to the point the image should be discarded and re-uploaded.
The :mobile version which is created new from the original is of excellent quality.
And the :card and :thumb versions remain the same, no difference.
Just the original is corrupted. Weird.
As a test, I re-ran the 'photo.image.recreate_versions!(:mobile)' several times to test different parameters trying to catch the corruption culprit (removed un-need gems, recreate :thumb version, etc.). But each time the quality of the original image got worst and worst.
And the higher the dpi the quicker the corruption: 300dpi first pass super ugly, 100dpi two passes yuck, and 72dpi after three passes is just criminal.
Corruption happens on localhost, as well as, Heroku (both staging and production).
Weird. I have used Carrierwave for years and this is the first time with such a problem.
ruby '2.4.1'
rails '5.1.7'
gem 'carrierwave', :git => 'https://github.com/carrierwaveuploader/carrierwave.git'
Here is the setup.
I pass the call to carrierwave recreate_version through Delayed_Job one user at a time
<% #user.photos.find_each do |photo| %>
<% photo.delay.recreate_mobile %>
<% end %>
and in the Photo model
class Photo < ApplicationRecord
def recreate_mobile
self.image.recreate_versions!(:mobile) if self.image?
end
end
and in the ImageUploader
class ImageUploader < CarrierWave::Uploader::Base
include ::CarrierWave::Backgrounder::Delay
include CarrierWave::MiniMagick
include CarrierWave::BombShelter
include CarrierWave::Processing::MiniMagick
storage :aws
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
process resize_to_limit: [1350, 1350]
process :store_dimensions
version :mobile do
process resize_to_limit: [400, 600]
end
version :card do
process resize_to_limit: [300, 460]
end
version :thumb, from_version: :card do
process resize_to_limit: [100, 150]
end
private
def store_dimensions
if file && model
model.width, model.height = ::MiniMagick::Image.open(file.file)[:dimensions]
end
end
def max_pixel_dimensions
[6024, 6024]
end
def extension_white_list
%w(jpg jpeg gif png)
end
end
and the gems
gem 'carrierwave-aws'
gem 'carrierwave', :git => 'https://github.com/carrierwaveuploader/carrierwave.git'
gem 'carrierwave_backgrounder'
gem 'carrierwave-bombshelter'
gem 'carrierwave-processing'
gem 'mini_magick'
gem 'remotipart', '~> 1.2'
Removed ALL of the unnecessary gems. Still a image corruption issue.
Quality of the original image and all versions are excellent.
It is just after running recreate_version the original image is corrupted.
Any ideas on how to prevent the original image quality from corrupting after recreate_version?
Solved it: switch processing to RMagick
Within the carriewave image_uploader.rb file
replace:
include CarrierWave::MiniMagick
include CarrierWave::Processing::MiniMagick
with:
include CarrierWave::RMagick
include CarrierWave::Processing::RMagick
MiniMagick is considered to have better memory management, but is rather outdated. Plus is corrupted the images. Fingers crossed RMagick has better memory management by now.
RMagick for the win!
I am using Carrierwave to upload images and that works fine but I am now trying to use Minimagick to process these uploaded images.
What is going on?
The images still upload as well as their thumb version, however both images are exactly the same size.
Here is the uploader code:
class FileUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
# Choose what kind of storage to use for this uploader:
storage :file
# Override the directory where uploaded files will be stored.
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# Create different versions of your uploaded files:
version :thumb do
process :resize_to_fit => [100, 100]
end
# Add a white list of extensions which are allowed to be uploaded.
def extension_white_list
%w(jpg jpeg gif png)
end
end
And here is how I am calling it:
<%= image_tag example.my_file.url(:thumb).to_s %>
I dont think it is anything to do with the way I am calling it because the two files created by all this are the same, so sound slike its to do with processing it on upload.
Here is the folder created for each object:
Image
--- Fixed ---
The issue was ImageMagick. It was not properly configured on my machine so that means no gem that deals with image processing (Paperclip, Minimagick or Dragonfly) could complete any image manipulation.
I want to use ffmpeg to make a screenshot of a uploaded video.
What I do is: uploading a video with carrierwave to amazonS3
when or while it is uploading I want to make a screenshot as thumbnail for this video.
How can I make this? How can I call ffmpeg with rails?
Thanks for your help
To do that, we are going to use the gem streamio-ffmpeg to run our FFMPEG commands from a rails library
require 'streamio-ffmpeg'
module ControllerVideoProcessor
def thumbnail path, second
movie = FFMPEG::Movie.new(path)
return movie.screenshot("some/temporal/path/screenshot.jpg", :seek_time => second)
end
end
As we can see, we have a function, which receives the path to the input video, and the second we want to get the thumbnail from. It is as simple as running the “screenshot” command of the streamio library, and that’s it. It will return a FFMPEG object, containing the image and it’s attributes.
Also if you use carrierwave gem for uploading your files you can use carrierwave plugin gem 'video_thumbnailer'
example
class VideoUploader < CarrierWave::Uploader::Base
include CarrierWave::RMagick
include VideoThumbnailer
storage :file
version :thumb do
process generate_thumb:[{quality:5, time_frame: '00:0:01', file_extension: 'jpeg'}]
def full_filename for_file
png_name for_file, version_name, "jpeg"
end
end
def png_name for_file, version_name, format
%Q{#{version_name}_#{for_file.chomp(File.extname(for_file))}.#{format}}
end
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
def extension_white_list
%w( mp4 jpg jpeg gif png )
end
end
Reference and more information about it you can find it here
http://ron-on-rails.tumblr.com/post/33720054493/getting-thumbnails-of-a-video-using-ffmpeg-and
https://github.com/teenacmathew/Video-Thumbnailer
You could use some gem that can talk to ffmpeg like this gem: https://github.com/streamio/streamio-ffmpeg
or you could call it through the command line similar to what is suggested in this question: Calling shell commands from Ruby
I have successfully implemented image uploading using carrierwave, fog and Amazon S3. In my imageuploader am using only fog as storage. But when i check my database i can see that just the file name is written instead of the amazon url. In my views its fetching correctly from aws without any issues.
Is it supposed to be like this?
If so how the application figure out the exact url to s3?
imageuploader.rb`
# encoding: utf-8
class ImageUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
# include CarrierWave::RMagick
# include CarrierWave::MiniMagick
include CarrierWave::MiniMagick
#Include the sprockets-rails helper for Rails 4+ compatibility:
include Sprockets::Rails::Helper
storage :fog
version :index_size do
process :resize_to_fill => [258, 173]
end
version :thumb_size do
process :resize_to_fill => [100, 100]
end
def extension_white_list
%w(jpg jpeg gif png)
end
end
Your config has the bucket name and the database has the filename. These are the only two pieces of information that are actually required to construct a filename (and it can be done without other API calls). The urls are actually pretty regular, so it is fairly straightforward for the server to do this. Hope that helps!
I am using carrierwave to upload a video then have a version called thumb with a custom processor that takes the video and creates a screenshot using streamio-ffmpeg. Both the video and the file are uploaded correctly but when calling uploader.url(:thumb) I get:
ArgumentError: Version thumb doesn't exist!
VideoUploader.rb
require 'carrierwave/processing/mime_types'
require 'streamio-ffmpeg'
class VideoUploader < CarrierWave::Uploader::Base
include CarrierWave::VideoConverter
include CarrierWave::MimeTypes
process :set_content_type
storage :file
version :thumb do
process :create_thumb
#def full_filename(for_file)
# "thumb_#{File.basename(for_file, File.extname(for_file))}.png"
#end
end
def create_thumb
cached_stored_file! if !cached?
movie = FFMPEG::Movie.new(current_path)
dirname = File.dirname(current_path)
thumb_path = "#{File.join(dirname, File.basename(path, File.extname(path)))}.png"
movie.screenshot(thumb_path, :seek_time => 5)
File.rename thumb_path, current_path
end
def file_identifier
model[:video]
end
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
return "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.user_id}/#{model.id}"
end
end
Then model.video_url(:thumb) returns the argument error. I am not sure what to do or why the version isn't registered any help would be great, thanks.
Fix
What contributed to the error was a mix of restarting the server but not restarting the rails console. Once i did this the Argument error went away but I was getting the wrong path. So i uncommented
def full_filename(for_file)
"thumb_#{File.basename(for_file, File.extname(for_file))}.png"
end
and used
[model].video.recreate_versions!
to correct any errors in the paths or naming schemes that could have occured
most likely some step in your create_thumb method is failing and thus the thumb is never created and has no URL. Are there any exceptions being thrown to your logs?
Perhaps you need to specify the FFMPEG binary location:
FFMPEG.ffmpeg_binary = '/usr/local/bin/ffmpeg'