An introductory tutorial on image processing in Ruby on Rails _ruby topics

Source: Internet
Author: User
Tags imagemagick image optimizer ruby on rails

Images can be said to be a critical part of any application. From social networks to a simple bug tracker, images play an important role. Managing images, however, is not an easy task and requires a lot of time and energy to plan ahead.

This article demonstrates how to achieve this goal in rail. How do you handle your images and create multiple versions in the background? How to improve the performance of the page by compressing the image without compromising the image quality? These are the one by one ways to listen to this article.
Entry

This tutorial is run in Rails 4.2, rendering views through the MongoDB database and Haml. However, the fragments shown in this article should be compatible with any rails version (albeit with some configuration differences).

Decorate the stage

ImageMagick is a powerful, stable, and open source Toolset and development Kit that you can install on your computer through package management.

On Ubuntu:

sudo apt-get-y install imagemagick
sudo apt-get-y install libmagic-dev sudo apt-get-y install Libmagickwand-dev


On Mac OS x, it is recommended that you use a homemade program:

Brew Install ImageMagick

Now we need a Ruby adapter that connects to the local ImageMagick library. You can use Minimagick, because it is lightweight:

# gemfile
 
Gem ' Mini_magick '

Characteristics of Minimagick

Before we begin, let's take a look at some of the minimagick features to avoid unnecessary errors.

Open the Rails console (rails c) and run the following code:

# Open an image from a website
 
image = Minimagick::image.open ("yun_qi_img/85.jpg")
 
# Get the image ' s width
ima Ge.width # 4928
 
# Get the image ' s height
image.height #3264

Let's tweak it to fit our ipad:

Image.resize "2048x1536" # now get the
 
image ' s new width and height
 
p ' width is => #{image.width} and ' => #{image.height} "

Where are the changed files stored?

Image.path # Temp Path

Manipulating images stored to a temporary path has the danger of disappearing. So to put it on the disk, a simple call writing method is as follows:

Image.write "Public/uploads/test.jpg"

Converting images

Perhaps one of your most common jobs is to convert images into different formats. Minimagick can simplify this process:

Image.format "PNG"
image.write "Public/uploads/test.png"

You can also put multiple operations in the same module:

Image.combine_options do |i|
 I.resize "2048x1536"
 i.flip
 i.rotate " -45" I.blur "
 0x15"
end
image.write "public/uploads/" Blur.png "
 
![ Some Weird result] (blur.png)

So let's take a look at how to relate these to our rails application.
Uploading Files

Carrierwave simplifies uploading files in Ruby, and it interacts well with Minimagick.

# gemfile
 
gem ' carrierwave '
gem ' carrierwave-mongoid ',: Require => ' carrierwave/mongoid '

Note: If you are on ActiveRecord or datamapper, the configuration will be slightly different. Carrierwave Official documentation describes the correct approach and points to this entry.

Get:

Bundle Install

Create first upload:

#app/uploaders/image_uploader.rb
 
class Imageuploader < carrierwave::uploader::base
 # Include Rmagick or Minimagick support:
 include Carrierwave::minimagick
 
 # Choose What kind of storage to use for this Uploader:
 St Orage:file
 # Override The directory where uploaded files would be stored.
 # This is a sensible default for uploaders so are meant to be mounted:
 def store_dir
  "Uploads/images"
 end
   end

This code is a storage:file that instructs the server to store the image on the local server, store_dir the specified location.

Since files are transmitted over the Internet, the incoming files will always be filtered:

# app/uploaders/image_uploader.rb ...
# ADD A white list of extensions which are allowed to be uploaded.
# for images your might use something like this:
def extension_white_list
 %w (jpg jpeg png gif)
end
...

Placing this upload into our image model:

# APP/MODELS/IMAGE.RB
 
class image
 include mongoid::D ocument
 include Mongoid::timestamps
 include Mongoid::P Aranoia
 include mongoid::attributes::D ynamic
 include Rails.application.routes.url_helpers
 
 Mount_uploader:media, Imageuploader, mount_on:: Media_filename End


Edit the IMAGE_UPLOADER.RB to process the uploaded image:

# app/uploaders/image_uploader.rb
 
#
... Process:resize_to_fill => [MB]
process:convert => ' png ' ...


Try to create a new image from the Rails console:

Media = File.Open ("/users/test/desktop/image/jpg")
img = image.new (: Media => Media)
Img.save

The upload image is available under Store_dir. However, the uploaded image is immediately processed and overwritten by the 200x200 image. We do not have a copy of the original document left for later editing. So to avoid this, we need to create multiple versions of the file.

# app/uploaders/image_uploader.rb
 
#
... Version:thumb do
 process:resize_to_fit => [MB]
 process:convert => ' jpg ' End
 
version: Cover  do
 process:resize_to_fit => [the 180]
 process:convert => ' jpg ' end
 
# ...

The following shows the previous code created two versions, and the check version is created by Carrierwave:

IMG.MEDIA.VERSIONS[:THUMB] # Returns the thumb image instance
Img.media.versions[:cover] # returns the cover image in Stance

Have you noticed that these images are generated instantaneously? This means that the image transformation occurs on the same thread, and execution is blocked until it is complete. In production applications, it is undesirable to create multiple versions of an image on the same line Chengri. On the contrary, we should deal with this situation conditionally.

# APP/UPLOADERS/IMAGE_UPLOADER/RB
 
# ....
Version:cover,: If =>: Is_live?
 do Process:resize_to_fit => [the 180]
 process:convert => ' jpg ' End
 
def is_live? ( img = nil)
 @is_live
end
 
def is_live= (value)
 @is_live = value
End
# ....

This way, when we create a new image, the copy will not be generated. We can manually trigger when needed and run the following code:

Img.media.is_live = True
img.save
img.media.recreate_versions!: Cover

This code is also run at the foreground, is a blocking operation, but at least can be postponed to the last minute as far as possible. We can run further through Resque in the background:

# LIB/RESQUE/IMAGE_QUEUE.RB
class imagequeue
 @queue =: Image_queue
 def self.perform (image_id)
  image = Image.find image_id
  img.media.is_live= true
  img.save
  img.media.recreate_versions!: Cover
 End End


Then, queue:

Resque.enqueue (Imagequeue, img.id.to_s)

Performance improvement

Images are heavy and tend to slow down the site. One way to reduce the burden of a page is to compress the images. Carrierwave Image Optimizer can help us to compress images quickly.

Add the following paragraph to the gemfile:

Gem ' Carrierwave-imageoptimizer '

Then edit image_uploader:

# app/uploaders/image_uploader.rd
 
#
 
... Include Carrierwave::imageoptimizer
process:optimize
process:quality => ...
.

This compression does not have visual loss.

Image processing is a huge vertical and we almost only touch the surface. We can build a lot of cool things. If you are interested in this article, please share your thoughts in the comments.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.