图像可以说是任何应用至关重要的一部分。从社交网络到一个简单的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("https://s3.amazonaws.com/StartupStockPhotos/20140808_StartupStockPhotos/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"htmlcode">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
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新动态
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]