ruby中使用MiniMagick处理图片
原文地址:http://www.blogkid.net/archives/2154.html
我曾经写过两篇关于和web开发中处理图片有关的文章,一篇是在PHP中如何裁剪图片,对比了ECShop/Babel这两套系统的做法,侧重于对图片本身的操作;另一篇是在rails项目中如何上传图片,侧重于上传并保存的策略,即使上传的是pdf文档,也一样适用。
最近我手头的项目里需要提供用户上传图片作为头像的功能,于是需要有一些后端的处理过程,比如裁剪、缩放。项目基于Rails框架,所以得找ruby上的实现。有人会推荐用attachment_fu/file_column这些插件,都显得太麻烦,我要的只是用户上传之后,经过适当裁剪,然后缩放到想要的尺寸。仅此而已。花了半天时间来研究,中文的参考资料有限,我把我的收获写下来,希望能对大家有帮助。
原来想用RMagick,但据说内存泄露的问题比较厉害,作为替代品MiniMagick不存在内存泄露的问题。而二者都是使用ImageMagick的,所以需要下载并安装ImageMagick。之后使用”gem install mini_magick“安装好MiniMagick,基础设施就搭建好了。
在开始之前,先思考一下,用于做用户头像的图片应该如何裁剪?我的考虑是所有用户采用同样的尺寸,比如48×48。但用户上传的图片往往不是正方形的,如果直接缩小到正方形,人像必然会变形。所以需要先切除一部分,把图片切成正方形,然后再缩小到想要的尺寸。

上面是原始图片(尺寸为2048×1536),先把它变成正方形。我能想到的最好办法就是在左右两边各截掉一部分,使处理后宽度和高度相等,这样能留下中间主体部分。如图(阴影部分为裁去部分,示意图不保证精确):

对于高度大于宽度的图片这招一样适用。得到中间的部分再进行缩放,就可以保证图片不失真。下面看看具体实现。
MiniMagick中Image对象有一个shave方法,正好可以满足这个需求。在irb中运行:
require ‘mini_magick’
img = MiniMagick::Image.from_file “1.jpg”
#取得宽度和高度
w,h = img[:width],img[:height] #=> [2048, 1536]
shaved_off = ((w-h)/2).round #=> 256
img.shave “#{shaved_off}x0″ #此处表示宽度上左右各截取256个像素,高度上截取0像素
img.write “2.jpg”
在使用shave方法处理后,图片已经是正方形了(像素数1536×1536)。此时保存得到的2.jpg如图:

之后想得到不同尺寸的缩略图,只消调用resize方法。
img.resize 100
img.write “3.jpg”
得到的3.jpg如下图:

当然,想要其他尺寸也可以多次调用resize。这个示例只是在irb中操作,在实际的项目中,应该先判断一下宽度和高度哪个大,决定从哪个维度上截取,也需要考虑一下存储策略。但总体来说,只要调用一次shave,调用一次resize,就能达到目的。
参考:http://atomgiant.com/2006/07/19/resizing-images-with-minimagick/


不错的东西
ruby上的东西都是这么便捷易用,如果做得难用,都不好意思拿出来
挺帅气 哈哈
@loveblogearn
多谢:)
唉,不知道为啥,我的ImageMagick总是安装不成功,而且报的错是Ruby.exe的Runtime error,郁闷死了……
大家有没有遇到过,
MiniMagick 处理含有中文路径或中文文件名不能成功的问题
@test
我还真没试过。。
请问一下楼主,遇到过这样的错误没?我在一台电脑上运行一切正常,然后在另一台电脑上就死活不行……:(
>> require “mini_magick”
=> []
>> img = MiniMagick::Image.from_file “d:\\www\\NLK.JPG”
MiniMagick::MiniMagickError: ImageMagick command (“identify C:/DOCUME~1/ADMINI~1
/LOCALS~1/Temp/mini_magick3040-2..JPG”) failed: {:output=>”‘identify’ \262\273是
内\262\277\273蛲獠\277命令\243\254也\262\273是\277稍诵械某绦?
或批\264\246理文\274\376\241\243\n”, :status_code=>#}
from D:/ruby/ruby/lib/ruby/gems/1.8/gems/mini_magick-1.2.5/lib/mini_magick.rb:157:in `run_command’
from D:/ruby/ruby/lib/ruby/gems/1.8/gems/mini_magick-1.2.5/lib/mini_magick.rb:47:in `initialize’
from D:/ruby/ruby/lib/ruby/gems/1.8/gems/mini_magick-1.2.5/lib/mini_magick.rb:28:in `new’
from D:/ruby/ruby/lib/ruby/gems/1.8/gems/mini_magick-1.2.5/lib/mini_magick.rb:28:in `from_blob’
from D:/ruby/ruby/lib/ruby/gems/1.8/gems/mini_magick-1.2.5/lib/mini_magick.rb:34:in `from_file’
from D:/ruby/ruby/lib/ruby/gems/1.8/gems/mini_magick-1.2.5/lib/mini_magick.rb:33:in `open’
from D:/ruby/ruby/lib/ruby/gems/1.8/gems/mini_magick-1.2.5/lib/mini_magick.rb:33:in `from_file’
from (irb):12
@六翼
是因为路径包含中文么?我没遇到过。。
貌似不是中文的问题,研究不明白,被我扔一边去了……
换个问题问LZ吧:这个MiniMagick里的这些方法(比如,我怎么知道它的切割方法叫shave而不叫cut?),你是从它的文档里找到的么?我想找一份全的但不知道怎么找……能不能指点一下?谢谢
@六翼
这个好办
你使用ruby的irb,然后向查看一个对象的方法,可以直接调用obj.methods。所有方法就列出来了。
然后找找你看着像的。
看着像的……原来也是蒙么,汗一下…………
@六翼
其实很容易就看到了啊
我试了一下,列出来的方法里连“shave”都没有哎,好像它列的是公用的方法吧……
不会啊,比如对象名是xxx,直接用xxx.methods就能看到所有方法了。包括shave
就是这样的:
irb(main):001:0> require ‘mini_magick’
=> []
irb(main):002:0> z=MiniMagick::Image.from_file(“2.jpg”)
=> #<MiniMagick::Image:0x4777d0c @path="C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/mini_magick4884-0..jpg", @tempfile=#>
irb(main):003:0> z.methods
=> [“inspect”, “to_param”, “___private_method_signatures”, “< z.shave “20×20″
=> #<MiniMagick::Image:0x4777d0c @path="C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/mini_magick4884-0..jpg", @tempfile=#>
哎,中间一串被吃掉了:
irb(main):001:0> require ‘mini_magick’
=> []
irb(main):002:0> z=MiniMagick::Image.from_file(“2.jpg”)
=> #<MiniMagick::Image:0x4777d0c @path="C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/mini_magick4884-0..jpg", @tempfile=#>
irb(main):003:0> z.methods
=> ["inspect", "to_param", "___private_method_signatures", "<<", "extend_with_included_modules_from", "clone", "tempfile", "output", "___declared_private_methods", "subclasses_of", "public_methods", "format_option", "display", "suppress", "method_missing", "instance_variable_defined?", "equal?", "freeze", "extended_by", "methods", "respond_to?", "enable_warnings", "instance_values", "write", "dup", "___method_signatures", "instance_variables", "__id__", "to_json", "b64encode", "unloadable", "eql?", "method", "copy_instance_variables_from", "id", "send", "singleton_methods", "silence_stderr", "to_yaml_style", "require_gem", "instance_exec", "decode64", "encode64", "load", "taint", "instance_variable_get", "frozen?", "require_library_or_gem", "instance_of?", "__send__", "windows?", "to_a", "dclone", "`", "type", "object_id", "instance_eval", "protected_methods", "silence_stream", "remove_subclasses_of", "to_yaml_properties", "___declared_methods", "==", "returning", "decode_b", "require", "===", "instance_variable_set", "to_blob", "extend", "kind_of?", "to_s", "daemonize", "class", "hash", "path", "private_methods", "=~", "tainted?", "run_command", "taguri", "to_yaml", "with_options", "blank?", "format", "untaint", "nil?", "gem", "silence_warnings", "taguri=", "combine_options", "is_a?", "[]“]
irb(main):004:0> z.shave “20×20″
=> #<MiniMagick::Image:0x4777d0c @path="C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/mini_magick4884-0..jpg", @tempfile=#>
这有点奇怪哎。
有个可能就是shave不是这个对象的方法,而是通过类似method_messing的方式来做的
又研究了一下,发现这里的好多都可以改成Ruby形式来用
http://www.imagemagick.org/script/mogrify.php
比如它写:
-noise radius add or reduce noise in an image
在Ruby里可以写:
img.noise “10″
就生成了一个半径10的噪点
不知道是不是所有的,但可以玩一阵子了,嘿嘿
好像第一次见到博主,靓仔一个啊
@月饼
呵呵,刚打开还以为你说今天的wordcamp呢。我寻思明明没去啊。
楼主也用ruby啊..
看了一下minimagick的源码。只有两文件,280行代码。
就是通过method_missing来实现的。结合magick的命令行..
[quote]Option Description
-adaptive-blur geometry adaptively blur pixels; decrease effect near edges
-adaptive-resize geometry adaptively resize image with data dependent triangulation.
-adaptive-sharpen geometry adaptively sharpen pixels; increase effect near edges
-adjoin join images into a single multi-image file
-affine matrix affine transform matrix
-alpha on, activate, off, deactivate, set, opaque, copy”, transparent, extract, background, or shape the alpha channel
-annotate geometry text annotate the image with text
-antialias remove pixel-aliasing
-append append an image sequence
-authenticate value decipher image with this password
-auto-gamma automagically adjust gamma level of image
-auto-level automagically adjust color levels of image
-auto-orient automagically orient image
-average average an image sequence
-background color background color
-bench iterations measure performance
-bias value add bias when convolving an image
-black-threshold value force all pixels below the threshold into black
-blue-primary point chromaticity blue primary point
-blue-shift factor simulate a scene at nighttime in the moonlight
-blur geometry reduce image noise and reduce detail levels
-border geometry surround image with a border of color
-bordercolor color border color
-caption string assign a caption to an image
-cdl filename color correct with a color decision list
-channel type apply option to select image channels
-charcoal radius simulate a charcoal drawing
-chop geometry remove pixels from the image interior
-clip clip along the first path from the 8BIM profile
-clamp restrict colors from 0 to the quantum depth
-clip-mask filename associate clip mask with the image
-clip-path id clip along a named path from the 8BIM profile
-clone index clone an image
-clut apply a color lookup table to the image
-contrast-stretch geometry improve the contrast in an image by `stretching’ the range of intensity value
-coalesce merge a sequence of images
-colorize value colorize the image with the fill color
-colors value preferred number of colors in the image
-colorspace type set image colorspace
-combine combine a sequence of images
-comment string annotate image with comment
-compose operator set image composite operator
-composite composite image
-compress type image compression type
-contrast enhance or reduce the image contrast
-convolve coefficients apply a convolution kernel to the image
-crop geometry crop the image
-cycle amount cycle the image colormap
-decipher filename convert cipher pixels to plain
-debug events display copious debugging information
-define format:option define one or more image format options
-deconstruct break down an image sequence into constituent parts
-delay value display the next image after pausing
-delete index delete the image from the image sequence
-density geometry horizontal and vertical density of the image
-depth value image depth
-despeckle reduce the speckles within an image
-display server get image or font from this X server
-dispose method layer disposal method
-distort type coefficients distort image
-dither method apply error diffusion to image
-draw string annotate the image with a graphic primitive
-edge radius apply a filter to detect edges in the image
-emboss radius emboss an image
-encipher filename convert plain pixels to cipher pixels
-encoding type text encoding type
-endian type endianness (MSB or LSB) of the image
-enhance apply a digital filter to enhance a noisy image
-equalize perform histogram equalization to an image
-evaluate operator value evaluate an arithmetic, relational, or logical expression
-extent geometry set the image size
-extract geometry extract area from image
-family name render text with this font family
-fft implements the discrete Fourier transform (DFT)
-fill color color to use when filling a graphic primitive
-filter type use this filter when resizing an image
-flatten flatten a sequence of images
-flip flip image in the vertical direction
-floodfill geometry color floodfill the image with color
-flop flop image in the horizontal direction
-font name render text with this font
-format string output formatted image characteristics
-frame geometry surround image with an ornamental border
-function name apply a function to the image
-fuzz distance colors within this distance are considered equal
-fx expression apply mathematical expression to an image channel(s)
-gamma value level of gamma correction
-gaussian geometry reduce image noise and reduce detail levels
-geometry geometry preferred size or location of the image
-gravity type horizontal and vertical text placement
-green-primary point chromaticity green primary point
-help print program options
-identify identify the format and characteristics of the image
-ifft implements the inverse discrete Fourier transform (DFT)
-implode amount implode image pixels about the center
-insert index insert last image into the image sequence
-intent type type of rendering intent when managing the image color
-interlace type type of image interlacing scheme
-interline-spacing value the space between two text lines
-interpolate method pixel color interpolation method
-interword-spacing value the space between two words
-kerning value the space between two characters
-label string assign a label to an image
-lat geometry local adaptive thresholding
-layers method optimize or compare image layers
-level value adjust the level of image contrast
-limit type value pixel cache resource limit
-linear-stretch geometry linear with saturation histogram stretch
-liquid-rescale geometry rescale image with seam-carving
-log format format of debugging information
-loop iterations add Netscape loop extension to your GIF animation
-mask filename associate a mask with the image
-mattecolor color frame color
-median radius apply a median filter to the image
-modulate value vary the brightness, saturation, and hue
-monitor monitor progress
-monochrome transform image to black and white
-morph value morph an image sequence
-motion-blur geometry simulate motion blur
-negate replace every pixel with its complementary color
-noise radius add or reduce noise in an image
-normalize transform image to span the full range of colors
-opaque color change this color to the fill color
-ordered-dither NxN ordered dither the image
-orient type image orientation
-page geometry size and location of an image canvas (setting)
-paint radius simulate an oil painting
-ping efficiently determine image attributes
-pointsize value font point size
-polaroid angle simulate a Polaroid picture
-posterize levels reduce the image to a limited number of color levels
-preview type image preview type
-print string interpret string and print to console
-process image-filter process the image with a custom image filter
-profile filename add, delete, or apply an image profile
-quality value JPEG/MIFF/PNG compression level
-quantize colorspace reduce image colors in this colorspace
-quiet suppress all warning messages
-radial-blur angle radial blur the image
-raise value lighten/darken image edges to create a 3-D effect
-random-threshold low,high random threshold the image
-recolor matrix translate, scale, shear, or rotate image colors.
-red-primary point chromaticity red primary point
-regard-warnings pay attention to warning messages.
-region geometry apply options to a portion of the image
-remap filename transform image colors to match this set of colors
-render render vector graphics
-repage geometry size and location of an image canvas
-resample geometry change the resolution of an image
-resize geometry resize the image
-respect-parentheses settings remain in effect until parenthesis boundary.
-roll geometry roll an image vertically or horizontally
-rotate degrees apply Paeth rotation to the image
-sample geometry scale image with pixel sampling
-sampling-factor geometry horizontal and vertical sampling factor
-scale geometry scale the image
-scene value image scene number
-seed value seed a new sequence of pseudo-random numbers
-segment values segment an image
-selective-blur geometry selectively blur pixels within a contrast threshold
-separate separate an image channel into a grayscale image
-sepia-tone threshold simulate a sepia-toned photo
-set attribute value set an image attribute
-shade degrees shade the image using a distant light source
-shadow geometry simulate an image shadow
-sharpen geometry sharpen the image
-shave geometry shave pixels from the image edges
-shear geometry slide one edge of the image along the X or Y axis
-sigmoidal-contrast geometry increase the contrast without saturating highlights or shadows
-size geometry width and height of image
-sketch geometry simulate a pencil sketch
-solarize threshold negate all pixels above the threshold level
-splice geometry splice the background color into the image
-spread radius displace image pixels by a random amount
-strip strip image of all profiles and comments
-stroke color graphic primitive stroke color
-strokewidth value graphic primitive stroke width
-stretch type render text with this font stretch
-style type render text with this font style
-swap indexes swap two images in the image sequence
-swirl degrees swirl image pixels about the center
-texture filename name of texture to tile onto the image background
-threshold value threshold the image
-thumbnail geometry create a thumbnail of the image
-tile filename tile image when filling a graphic primitive
-tile-offset geometry set the image tile offset
-tint value tint the image with the fill color
-transform affine transform image
-transparent color make this color transparent within the image
-transparent-color color transparent color
-transpose flip image in the vertical direction and rotate 90 degrees
-transverse flop image in the horizontal direction and rotate 270 degrees
-treedepth value color tree depth
-trim trim image edges
-type type image type
-undercolor color annotation bounding box color
-unique-colors discard all but one of any pixel color.
-units type the units of image resolution
-unsharp geometry sharpen the image
-verbose print detailed information about the image
-version print version information
-view FlashPix viewing transforms
-vignette geometry soften the edges of the image in vignette style
-virtual-pixel method access method for pixels outside the boundaries of the image
-wave geometry alter an image along a sine wave
-weight type render text with this font weight
-white-point point chromaticity white point
-white-threshold value force all pixels above the threshold into white
-write filename write images to this file[/quote]
ruby上的东西都是这么便捷易用,如果做得难用,都不好意思拿出来
这句话说的太对了。
ruby是改变许多程序员思维的良药