Pull to refresh

Загрузка изображений и последующая обработка в Ruby on Rails

Доброго времени суток. Сегодня я расскажу Вам про способы загрузки изображений и последующей их обработкой в Ruby on Rails. На момент написания в мире рельсовиков существует две популярные библиотеки для загрузки изображений – Paperclipи Carrierwave. Ну что, начнем знакомство?


Paperclip



Рассмотрим сперва Paperclip. Данный gem является одним из первых, если не первой, библиотекой для загрузки изображений. Для ее использования Вам необходимо всего лишь установить ImageMagick. Версия установок представлены ниже:

Ubuntu

sudo apt-get install libmagick9-dev

MacOs

brew install imagemagick

Windows

Разработка Ruby on Rails под этой ОС все еще проблематична, но этот пост должен помочь

Установив системные библиотеки, мы можем добавить paperclip в Gemfile:

gem ‘paperclip’

Либо установить через команду:

gem install paperclip

Следующим шагом будет привязка изображения к модели. Для этого нам стоит добавить несколько строк кода и столбцов в базе данных. Сперва создадим миграцию:

class AddAvatarColumnsToUser < ActiveRecord::Migration 
  def self.up     
    change_table :users do |t|  
      t.has_attached_file :avatar     
    end 
  end 
   
  def self.down   
    drop_attached_file :users, :avatar   
  end 
end


После нам необходимо добавить в нашу модель такой код:

сlass User < ActiveRecord::Base

  has_attached_file :avatar

end


На этом установка завершилась. Для загрузки изображений нам понадобится простенькая форма следующего вида:

<%=form_for user, :html => {:multipart => true} do |f|%> #не обязательно для rails >=3.1
…
<% =f.file_field :avatar %>
…


Для получения ссылки на загруженное изображение достаточно вызвать метод url:

user.avatar.url

Но допустим нам необходимо несколько версий изображений, различных по размеру. Все достаточно просто – необходимо добавить немного кода в инициализацию:

has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100>" }


Ссылки на объявленные версии можно получить так:

user.avatar.url(:medium)
user.avatar.url(:medium)


Более детально с возможностями библиотеки я предлагаю ознакомится самостоятельно вот здесь.

CarrierWave



Вторая библиотека появилась немного позже, но это не помешало ей получить большую популярность среди разработчиков и меня лично. Для ее работы также желательно установить библиотеки ImageMagick.

Добавим gem в наше приложение:

gem ‘carrierwave’ # через Gemfile

gem install carrierwave # для всей системы


Привязка к ActiveRecord модели также не составит большого труда. Сперва добавим строковое поле в таблицу модели базы данных:

add_column :users, :avatar, :string


А после создадим класс загрузчика. Для этого в gem-е есть неплохой генератор:

rails g uploader Avatar

После этого в папке app появится подкаталог uploaders с нашим загрузчиком. Следует заметить, что генератор создал класс AvatarUploader. Теперь осталось лишь добавить инициализацию загрузчика в модели:

mount :avatar, AvatarUploader


Форма загрузки изображения такая же как у paperclip, но с несколькими приятными бонусами в виде кеширования и препросмотра прокешированого изображения при ошибках в валидации:

<%= form_for @user, :html => {:multipart => true} do |f| %>   
  <p>
    <label>My Avatar</label>
    <%= image_tag(@user.avatar_url) if @user.avatar? %> #загруженая картинка, если присутствует
    <%= f.file_field :avatar %>
    <%= f.hidden_field :avatar_cache %> #кешированое изображение

Внимательный читатель мог заметить, что для получение ссылки на загруженную картинку есть метод avatar_url или avatar.url.

Загрузчик CarrierWave



Теперь рассмотрим внутренности нашего загрузчика. Сгенерированные комментарии позволят, не зная библиотеки, прекрасно сконфигурировать загрузчик. В первую очередь стоит выделить настройку хранилища. Доступны такие варианты как :file и :fog. Первый вариант будет хранить изображения в каталоге public/uploads, второй – на внешних серверах загрузки изображений(Amazon, Google и тп.)

Следующим шагом в настройке загрузчика становится выбор библиотеки для обработки изображения. Выбор сводится к двум вариантам — RMagick и MiniMagick. Оба этих gem-а используют ImageMagick, но MiniMagick использует меньше ресурсов, не лишая базового функционала. Добавим его в наш Gemfile.

gem ‘mini_magick’

Сделав это, мы получаем доступ к нескольким основным функциям для обработки изображений. Например, resize_to_fit, resize_to_fill или convert. Для применения их достаточно добавить строчку

process :resize_to_fit => [200, 300]


Это сожмет картинку до таких размеров, чтоб она влезла в площадь 200х300. Для создания различных версии загруженного изображения необходимо добавить следующее:

version :thumb do
  process :resize_to_fit => [50, 50]
end


user.avatar.thumb.url #ссылка на данную версию картинки.


Дополнительная обработка



А что если нужно сделать больше, чем изменить размер изображения или сконвертировать в другой формат. Представим, что для какой-то версии нужна рамка вокруг изображения:

version :with_border do

   process :draw_border

end

private

def draw_border
  manipulate! do |image|
    image.frame “5x5”# рамка с толщиной 5 пикселей в вертикальном и горизонтальном положениях

    image
  end
end


Метод manipulate! принимает блок, в котором доступно загруженное изображение. В данном блоке мы можем выполнять почти все описанные здесь операции. Важным моментом при манипуляции с изображением в блоке manipulate! – блок должен возвращать оперируемое изображение.
Но вот незадача, цвет рамки нам не нравится. Исправим ситуацию с помощью метода combine_options:

def draw_border
  manipulate! do |image|
    image.combine_options do |c|
      c.mattecolor “Yellow”#задает основной цвет. Кроме указания имени, можно задать цвет в формате rgb(x,y,z) и #xxyyzz
      c.frame “5x5”
    end
    
    image   
  end
end


Данный метод позволяет задать несколько параметров для одной операции ImageMagick. Если вам необходимо выполнить несколько операций над версией, то желательно все операции собрать в одном методе, и его вызвать в process:

version :thumb do

   process :make_thumb

end

private

def make_thumb
  resize_to_fit(50,50)
  draw_border
end


И самом конце, давайте создадим скругленные края нашим картинкам. Как округлить края и прочие интересные трансформации изображения можно найти здесь. Версия для carrierwave представлена ниже:

def round_corner(radius = 10)
    round_command = ""
    round_command << '\( +clone -alpha extract '
    round_command << "-draw 'fill black polygon 0,0 0,#{radius} #{radius},0 fill white circle #{radius},#{radius} #{radius},0' "
    round_command << '\( +clone -flip \) -compose Multiply -composite '
    round_command << '\( +clone -flop \) -compose Multiply -composite \) '
    round_command << '-alpha off -compose CopyOpacity -composite'
    manipulate! do |image|
      image.format 'png'
      image.combine_options :convert do |command|
 	command << shadow_command
      end

    image
  end
end


На этом я хочу с вами попрощаться. Надеюсь мой пост был полезным и пригодится Вам на практике.
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.
Change theme settings