Ruby on Rails下的图像处理入门教程_ruby专题

图像可以说是任何应用至关重要的一部分。从社交网络到一个简单的Bug追踪器,图像都扮演着重要的角色。然而管理图像并不是一件容易的事情,需要提前耗费大量的时间精力去计划。

本文演示了如何在Rail中实现这一目标。如何处理你的图像以及在后台创建多个版本?如何通过压缩图像又不损图像质量,以此来提高页面性能?这些且听本文一一道来。
入门

本文教程是运行于Rails 4.2,通过MongoDb数据库和HAML呈现视图。不过本文所展示的片段应该兼容任何Rails版本(尽管有些配置差异)。

布置舞台

ImageMagick是一套功能强大、稳定而且开源的工具集和开发包,你可以通过包管理把它安装在你的电脑上。

Ubuntu上:

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

Mac OS X上,建议使用自制程序:

brew install imagemagick

现在我们需要一个连接到本地ImageMagick库的Ruby适配器。你可以使用MiniMagick,因为它是轻量级的:

# Gemfile

gem 'mini_magick'

MiniMagick的特性

在正式开始之前,让我们先了解一下某些MiniMagick的特性,以避免不必要的错误。

打开Rails控制台(Rails c)并运行以下代码:

# Open an image from a website

image = MiniMagick::Image.open("yun_qi_img/85.jpg")

# Get the Image's width
image.width # 4928

# Get the image's height
image.height #3264

让我们调整一下以适应我们的iPad:

image.resize "2048x1536"

# Now get the image's new width and height

p "Width is => #{image.width} and height is => #{image.height}"

更改后的文件存储在哪呢?

image.path # temp path

操纵图像存储到一个临时的路径有消失的危险。所以要把它放到磁盘中,一个简单的调用编写方法如下:

image.write "public/uploads/test.jpg"

转换图像

或许你最常见的工作之一就是将图像转换成不同的格式。MiniMagick可以简化这一过程:

image.format "png"
image.write "public/uploads/test.png"

你还可以将多个操作放在同一模块中:

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)

至此,让我们来看看如何将以上的这些与我们的Rails应用联系到一起。
上传文件

Carrierwave简化了在Ruby中上传文件,同时它与MiniMagick交互的也很好。

# Gemfile

gem 'carrierwave'
gem 'carrierwave-mongoid', :require => 'carrierwave/mongoid'

注意:如果你是在ActiveRecord或DataMapper上,配置会稍微不同。Carrierwave官方文档介绍了正确的方法,点此进入。

获取:

bundle install

创建第一个上传:

#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:
 storage :file
 # 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
  "uploads/images"
 end
end

这段代码是自说明,storage :file指示服务器将图像存储在本地服务器上,store_dir指定位置。

自从文件通过互联网传送,总会过滤传入的文件:

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

将这种上传置入我们的图像模型:

# app/models/image.rb

class Image
 include Mongoid::Document
 include Mongoid::Timestamps
 include Mongoid::Paranoia
 include Mongoid::Attributes::Dynamic
 include Rails.application.routes.url_helpers

 mount_uploader :media, ImageUploader, mount_on: :media_filename
end

编辑image_uploader.rb来处理上传的图像:

# app/uploaders/image_uploader.rb

#.....
process :resize_to_fill => [200, 200]
process :convert => 'png'
#.....

尝试从Rails控制台创建一个新的图像:

media = File.open("/Users/test/Desktop/image/jpg")
img = Image.new(:media => media)
img.save

上传图像在store_dir下是可用的。然而上传的图像是立即被处理的,并被200×200的图像覆盖。我们没有原始文件的副本留作以后编辑。所以为避免这种情况,我们需要创建多个版本的文件。

# app/uploaders/image_uploader.rb

#.....
version :thumb do
 process :resize_to_fit => [100, 100]
 process :convert => 'jpg'
end

version :cover  do
 process :resize_to_fit => [240, 180]
 process :convert => 'jpg'
end

#.....

下面显示的是上段代码创建两个版本,检查版本由Carrierwave创建:

img.media.versions[:thumb] # returns the thumb image instance
img.media.versions[:cover] # returns the cover image instance

你注意到这些图像是瞬间生成的吗?这意味着图像转换发生在同一线程中,并且执行是被阻塞的,直到完成为止。在生产应用中,在同一线程里创建一个图像的多个版本是不受欢迎的。相反,我们应该有条件的处理这种情况。

# app/uploaders/image_uploader/rb

#....
version :cover, :if => :is_live? do
 process :resize_to_fit => [240, 180]
 process :convert => 'jpg'
end

def is_live?(img = nil)
 @is_live
end

def is_live=(value)
 @is_live = value
end
#....

这样,当我们创建一个新的图像时,副本将不会生成。我们可以在需要的时候手动去触发,运行如下代码:

img.media.is_live = true
img.save
img.media.recreate_versions! :cover

这代码也是运行于前台,是一个阻塞操作,但至少可以尽可能的推迟到最后一刻。我们可以通过Resque在后台进一步的运行:

# 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

然后,列队:

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

性能提升

图像是厚重的,往往会减慢网站。减少页面负担的一种方法是压缩这些图像。Carrierwave图像优化器可以帮助我们飞速的压缩图像。

将下面这段添加到Gemfile:

gem 'carrierwave-imageoptimizer'

然后编辑image_uploader:

# app/uploaders/image_uploader.rd

#.....

include CarrierWave::ImageOptimizer
process :optimize
process :quality => 100
#....

如此压缩不会有视觉丧失。

图像处理是一个巨大的垂直,我们几乎只触及表面。我们可以建立很多很酷的东西。如果您对这篇文章感兴趣,请在评论中分享您的想法。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索ruby
rails
ruby on rails 入门、ruby on rails、ruby on rails 教程、ruby rails、ruby on rails 安装,以便于您获取更多的相关知识。

时间: 2024-10-20 03:12:39

Ruby on Rails下的图像处理入门教程_ruby专题的相关文章

Ruby on Rails框架程序连接MongoDB的教程_ruby专题

前边有介绍mongodb的安装以及ror项目的搭建,现在进行一下整合. 1.创建项目 创建项目时不再使用rails active_record支持 rails new todo -O 2.我们将要使用MongoMapper来驱动MongoDB到Rails 编辑GemFile,增加下面的内容 gem"mongo_mapper" 然后  执行 bundle install 安装gem bundle install 3.添加数据库链接 在config/initializer下面新建一个mon

在Ruby on Rails中优化ActiveRecord的方法_ruby专题

 Ruby on Rails 编程常常会将您宠坏.这一不断发展的框架会让您从其他框架的沉闷乏味中解脱出来.您可以用习以为常的几行代码片断表达自己的意图.而且还可以使用 ActiveRecord. 对于我这样的一个老 Java? 程序员而言,ActiveRecord 多少有点生疏.通过 Java 框架,我通常都会在独立的模型和模式之间构建一种映射.像这样的框架就是映射框架.通过 ActiveRecord,我只定义数据库模式:或者用 SQL 或者用称为迁移(migration)的 Ruby 类.将对

Ruby on Rails网站项目构建简单指南_ruby专题

创建 Rails 项目 创建一个普通的 Rails 项目,可以直接使用以下命令: rails new blog 但在国内因为连接 RubyGems 的速度太慢,而 Rails 默认在构建完项目结构后,会使用 bundle 命令从 RubyGems 下载安装依赖包.最后会因为网络问题而卡死.所以需要使用 --skip-bundle 参数跳过执行 bundle 这一步.然后使用国内的 Gems 镜像源来完成后面依赖包的安装.国内推荐的源是 Ruby China 提供的: https://gems.r

提升Ruby on Rails性能的几个解决方案_ruby专题

简介 Ruby On Rails 框架自它提出之日起就受到广泛关注,在"不要重复自己","约定优于配置"等思想的指导下,Rails 带给 Web 开发者的是极高的开发效率. ActiveRecord 的灵活让你再也不用配置繁琐的 Hibernate 即可实现非常易用的持久化,Github 和 Rubygems 上丰富多样的 Rails 插件是 Rails 开发高效率的又一有力保障.Rails 是一个真正彻底的 MVC(Model-View-Controller) 框

关于Ruby on Rails视图编写的一些建议_ruby专题

    不要直接从视图调用模型层.     不要在视图构造复杂的格式,把它们输出到视图 helper 的一个方法或是模型.     使用 partial 模版与布局来减少重复的代码.     加入 client side validation 至惯用的 validators. 要做的步骤有:         声明一个由 ClientSideValidations::Middleware::Base 而来的自定 validator        module ClientSideValidatio

Ruby程序中正则表达式的基本使用教程_ruby专题

Ruby大部分的内置类型都和其它的编程语言很相似.主要有strings,integers,floats,arrays等等.然而,只有脚本语言,如Ruby,Perl,和awk等提供了内置表达式类型的支持.正则表达式尽管比较隐蔽,但却是一个很强大的文本处理工具. 正则表达式是使用指定的模式匹配字符串的一种简单的方法.在Ruby中,创建正则表达式的典型方式是把模式写在两个斜线之间/pattern/. 毕竟,Ruby就是Ruby,正则表达式也是对象,也能像对象般操作. 例如,你可以使用下面的正则表达式写

Ruby on Rails在Ping ++ 平台实现支付_ruby专题

本地数据库创建订单表. 建议包含以下字段,参考官方API( https://pingxx.com/document/api): order_no:required 商户订单号,适配每个渠道对此参数的要求,必须在商户系统内唯一. alipay: 1-64 位, wx: 1-32 位, bfb: 1-20 位, upacp: 8-40 位, yeepay_wap:1-50 位, jdpay_wap:1-30 位, cnp_u:8-20 位, cnp_f:8-20 位, 推荐使用 8-20 位,要求数

关于Ruby on Rails路由配置的一些建议_ruby专题

当你需要加入一个或多个动作至一个 RESTful 资源时(你真的需要吗?),使用 member and collection 路由. # 差 get 'subscriptions/:id/unsubscribe' resources :subscriptions # 好 resources :subscriptions do get 'unsubscribe', on: :member end # 差 get 'photos/search' resources :photos # 好 resou

在Ruby on Rails中使用Markdown的方法_ruby专题

实现 Markdown 语法和代码语法高亮分别是用的 Redcarpet 和 pygments.rb 两个 Gem:     https://github.com/vmg/redcarpet     https://github.com/tmm1/pygments.rb     https://github.com/richleland/pygments-css     http://pygments.org/docs/lexers/ 在/Gemfile中添加如下两行: gem 'redcarp