Replacing RMagick with mini_magick with Paperclip - ruby-on-rails

I'm using RMagick and loving it, but it is eating up huge amounts of memory. Even a simple script would use over 100MB of Ram. On my local machine this isn't a problem, but on heroku my app crashes when a few users simultaneously upload Pictures.
I found mini_magick and trying to replace it in my Model's, but can't find a solution. This is my current Process Flow:
# Validations
validates :scr, presence: true
# Paperclip
has_attached_file :scr,
styles: {
index: ['220x170#', :jpg, quality: :better],
show: ['1000', :jpg, quality: :better],
original: ['100%', :jpg, quality: :better],
directionals: ['115x70#', :jpg]
},
convert_options: {
show: '-quality 90 -unsharp 3x0.4+0.4+0 -interlace Plane',
index: '-quality 90 -unsharp 3x0.4+0.4+0 -interlace Plane',
original: '-quality 90 -interlace Plane',
directionals: '-quality 90 -interlace Plane'
},
processors: [:thumbnail, :compression]
# Paperclip Validation
validates_attachment_content_type :scr, content_type: ['image/jpg', 'image/jpeg', 'image/png']
How can i replace RMagick and let Mini_magick do the Magic ?

remove Rmagick from gemfile.add minimagick to your gemfile and start using it
Add the gem to your Gemfile:
gem "mini_magick"
bundle install
####now start using it with callback/observer
image = MiniMagick::Image.open("input.jpg")
image.resize "100x100"
image.write "output.jpg"
OR
you can use delayed_paperclip for the same so that at runtime convert only those styles that you need on next page....rest put it in background for conversion using it without changing the code.
process_in_background :avatar, :only_process => [:show,:original,:directionals]
##assuming you next page only need style :index..

Related

Heroku ffmpeg buildpacks for video uploads

Is there a proper way to get heroku ffmpeg installed and running so that my users can upload videos in my rails app?
Tried the Heroku references on the topic which led to my app running the heroku error check logs page...
I know there has to be some installation I have to pass but don't seems to find anything on it - Please help with links or ideas :)
users can upload videos
We've had it working on Heroku before; we used paperclip-ffmpeg (which is now paperclip-av-transcoder) with the actual Paperclip gem.
Whilst I can't provide any information about the buildpacks, I can share how we were able to get video uploading working on Heroku...
#app/models/attachment.rb
class Attachment < ActiveRecord::Base
has_attached_file :attachment,
styles: { thumb: { geometry: "100x100#", format: 'jpg', time: 10}, medium: { geometry: "300x300#", format: 'jpg', time: 10} },
processors: [ :transcoder ]
end
As long as the paperclip-av-transcoder gem installs (ensure you've got it in your Gemfile), this should allow you to store the videos - and images - you need.
Got heroku Video uploads to work!
Video model:
has_attached_file :video, styles: {
:medium => {
:geometry => "640x480",
:format => 'mp4'
},
:thumb => { :geometry => "160x120", :format => 'jpeg', :time => 10}
}, :processors => [:transcoder]
validates_attachment_content_type :video, content_type: /\Avideo\/.*\Z/
Make sure you already bundled:
gem 'paperclip', '~> 4.3.1'
gem 'aws-sdk', '< 2.0'
gem 'paperclip-av-transcoder'
Run the paperclip migration:
rails g paperclip model video
Be sure to add in post_controller.rb:
private
def bscenes_params
params.require(:post).permit(:video)
end
Upload form:
<%= f.file_field :video %>
Show page:
<%= video_tag bscene.video.url(:medium), controls: true, style: "max-width: 100%;" %>
At this point you should get this error:
Av::UnableToDetect (Unable to detect any supported library):
Go to your terminal and type in:
brew options ffmpeg
Then run the following to install ffmpeg:
brew install ffmpeg --with-fdk-aac --with-ffplay --with-freetype --with-frei0r --with-libas
At this point video uploads will work locally
Now for remote uploads you will need to setup https://devcenter.heroku.com/articles/buildpacks
After setting up Heroku buildpacks you may get an error:
Av::UnableToDetect (Unable to detect any supported library)
You will need to create a Procfile in the root of your app directory more information about Procfile here: https://devcenter.heroku.com/articles/procfile
touch Procfile
Hope this helps!

How to update attachment using paperclip

I used paperclip to upload images to S3,
has_attached_file :attachment,
styles: { mini: '48x48>', small: '100x100>', product: '240x240>', large: '600x600>',larger: '860x1280>' },
default_style: :product
validates_attachment :attachment,
:presence => true,
:content_type => { :content_type => %w(image/jpeg image/jpg image/png image/gif) }
Now , I want to compress the images which are already uploaded to S3 using gem "paperclip-compression", so I added processors: [:thumbnail, :compression], How would I update all the attachments using a ruby script??. I am able to read and store image into file but unable to update the attachment with the file.
According to paperclip wiki you should use reprocess! method:
Model.each do |model|
model.attachment.reprocess!
end
Another option is to use rake task:
# only thumbnails style
rake paperclip:refresh:thumbnails CLASS=Model
# or all styles
rake paperclip:refresh CLASS=Model
# only missing styles
rake paperclip:refresh:missing_styles

rails paperclip - changing aspect ratio of uploaded image

Using paper clip, how can I change the aspect ratio of uploaded image.
Which is easier? Doing with jcrop or paperclip ?
I think paperclip would be nice but not sure where/how to keep the config options.
As for the paperclip you can easy do this by specifying convert options directly in your model. For example:
has_attached_file :photo,
:preserve_files => true,
:styles => { :medium => "800x800>",
:small => "300x300>",
:thumb => "150x150>" },
:convert_options => { :medium => "-quality 70 -interlace Plane -strip",
:small => "-quality 70 -interlace Plane -strip",
:thumb => "-quality 70 -interlace Plane -strip" },
:default_url => "/images/missing.png"
you can use that way any ImageMagick's conver option.
All supported options are described here.
BTW: if you want it to be processed in background than add this to your Gemfile:
gem 'delayed_job'
gem 'delayed_job_active_record'
gem 'delayed_paperclip'
gem 'daemons'
and this to the model:
process_in_background :photo, queue: 'paperclip_processing'
to run/stop a daemon:
RAILS_ENV=production bin/delayed_job -n 2 start
RAILS_ENV=production bin/delayed_job stop
and to see the progress and manage the queue this is great:
gem 'delayed_job_web'
Enjoy.
You'll need to use ImageMagick to get Paperclip to crop images. Paperclip only handles the upload process - it doesn't crop or store the images for you
I would recommend looking at how to use Paperclip with ImageMagick, and then you'll have to find a way to populate your models' styles option with ImageMagick commands:
has_attached_file :image, styles: { medium: "[[imagemagick code]]" }
ImageMagick change aspect ratio without scaling the image

AutoSmusher for amazon S3 to optimise images?

Any ruby implementation with paperclip to autosmush amazon s3 images?
PS: I googled and got this: https://github.com/grosser/smusher and works pretty nicely on my local machine. But to use something like this on amazon s3. It will be great to have an automated process for this and just smush newly created content. Any ideas?
Code I am using to some what optimise user uploaded images.
has_attached_file :attachment, {
:styles => {
:medium => ["654x5000000>", :jpg],
:small => ["260x50000000>", :jpg],
:thumb => ["75x75#", :jpg],
:facebook_meta_tag =>["200x200#", :jpg]
},
:convert_options => {
:medium => "-quality 80 -interlace Plane",
:small => "-quality 80 -interlace Plane",
:thumb => "-quality 80 -interlace Plane",
:facebook_meta_tag => "-quality 80 -interlace Plane"
},
:s3_headers => { 'Cache-Control' => 'max-age=315576000', 'Expires' => 10.years.from_now.httpdate }
}.merge(PAPERCLIP_STORAGE_OPTIONS)
But still images can be optimised. I got the gem smusher but confused how to use it. My current page ranking as per GTmetrics is here.
I have also been looking into lossless image compression with rails, and so far I think the best gem I have found is here. The instructions with the gem say to add a :processors option that gets passed a hash containing multiple processing options, such as :compression, which this gem defines. It also requires jpgtran and optipng to be installed, which I'm not sure if Amazon S3 has.

Rails Paperclip image compression compared to what Page Speed produces

I've set up paperclip in rails and everything is working hunky-dory (i actually had to google that...:).
I've noticed however that Page Speed tells me I could losslessly compress my thumbnail and large images (the ones that paperclip produces) further. Is there an option I can put into my model which does this? I've noticed that mod_deflate doesn't compress images (I'm using Firefox).
You can add compression to paperclip processing using the paperclip-compression gem.
In your Gemfile:
gem "paperclip-compression", "~> 0.1.1"
(of course run bundle install)
In your model:
has_attached_file :avatar,
:styles => { :medium => "300x300>", :thumb => "100x100>" },
:processors => [:thumbnail, :compression]
"jpegtran works by rearranging the compressed data (DCT coefficients), without ever fully decoding the image. Therefore, its transformations are lossless"
Note: if you are running on heroku, you'll need jpegtran, and optipng binaries added to your application. Here's a good article on running binaries on heroku.
You should do your own testing on various JPEG compression levels but I've noticed that I can bump ImageMagicks quality setting down to 75 and still not see any noticeable difference - with about a 30-40% file size savings.
My model looks like:
has_attached_file :photo,
:styles => {
:"185x138" => {
:geometry => "185x138>"
} },
:convert_options => {
:all => "-auto-orient",
:"185x138" => "-quality 75",
-quality 75 is for ImageMagick. If you're using a different processor you will need to adjust accordingly.
What about FFMPEG or AVCONV?
sudo apt-get install ffmpeg/avconv
= initializer
Paperclip.options[:command_path] = "/usr/bin/" # see `which ffmpeg`
= Modal
after_save :compress_with_ffmpeg
def compress_with_ffmpeg
[:thumb, :original, :medium].each do |type|
img_path = self.avtar.path(type)
Paperclip.run("ffmpeg", " -i #{img_path} #{img_path}")
end
end

Resources