前面讲到了 最简单的图像处理库CxImage,本文则推荐一个最强大的图像处理库ImageMagick,它被誉为命令行上的PhotoShop,而且被各大公司所采用。
1)下载
可从ImageMagick官方网站下载最新的ImageMagick源码进行编译 ,也可直接下载相应的编译好的二进制包直接安装。
官方网址: http://www.imagemagick.org/script/index.php
2)编译
windows下可直接用VC编译,linux下直接configure make install即可。
windows下编译分为两步:
a. 首先windows下需要编译ImageMagick自带的configure文件, configure是一个ImageMagick提供的配置工具,位于源代码中的\VisualMagick\configure目录。configure编译后会生成configure.exe可执行文件。然后运行configure.exe会出现配置对话框,如下所示:
下一步
根据需要选择工程的类型,多线程动态库,多线程静态库等。
选择图像每个通道的深度。一般情况下ARGB,每个通道8用位表示。而ImageMagick默认使用16位表示一个通道。
由于我们通常处理的都是8位的图像,这里需要调整为Q8。否则在处理图像时可能会有问题。
b. configure之后,会在源代码的根目录生成vc的工程文件,直接打开build就可以了。build的结果在源代码根目录下的bin目录。包括两部分:lib库和exe程序。即可以通过lib方式在程序中调用,也可以在命令行中调用。
3)注意
再特别说明一下,一定要注意位深度更改为8,否则编译出来的程序默认为每个颜色16位,在处理图片时会出错。
ImageMagick功能十分强大,不过也有些复杂。具体可以参考他的文档。位于源码根目录下的www目录。也可以直接点这里: http://www.imagemagick.org/script/index.php
由于本人未能详细研究,下面引用 http://www.netingcn.com/category/imagemagick中的内容进行简要说明:
说明:此文章有网友提供
见官方demo:http://www.imagemagick.org/Usage/thumbnails/#rounded%5Fborder
运行此demo必须条件:
1、ImageMagick 安装路径 D:/Program Files/ImageMagick/convert.exe
2、将 ex 文件夹放在 C盘根目录下。
最终转换命令
"convert c:/card1.jpg -alpha set -gravity center -extent 1200x750 " + " c:/a_big.png -compose DstIn -composite " + " c:/b_big.png -compose Over -composite " + " c:/111.png "
其中 a_big.png b_big.png 均是背景图 顺序不能互换 111.png 是生成的圆角图片
思路:
这里假设用户上传的最大长宽比例不超过1200*750,
我们可以先做 1200*750 2张背景图,frist_1200_750.png 和 sec_1200_750.png。
由于用户上传图片大小不同,也就是 width,height不同
1、得到用户上传图片的width、height
2、判断目录下是否存在此长宽比的背景图,如果不存在,再创建此长宽比的背景图,Radius.java createThumbnail 方法。
3、根据转换命令,进行转换。记住,2张背景图的顺序不能反, 读者可试试互换结果。 Radius.java createRadiusImg 方法。
4、测试,如果 width > height 生成的圆角图长宽比正常。测试图片 card1.jpg
如果 width < height,就不正常了。 测试图片 4d58cae79da70.jpg 如果 width > height, 长宽比均比较大,生成图片 和 原图片对比,发现生成图片模糊,测试图片 200711108226923_2.jpg
Demo代码下载地址: http://pan.baidu.com/netdisk/singlepublic?fid=588935_3480700337
图片反色处理通过convert的 negate参数来实现,同时可以针对制定的区域进行反色。
convert -negate src.jpg negate.jpg
效果图如下:
convert -region 100x100+0+0 -negate src.jpg negate-part-1.jpg convert -gravity center -region 100x100+0+0 -negate src.jpg negate-part-2.jpg
注意: regoin参数需要在 negate前,否则无法对指定的区域进行反色处理。另外关于 gravity参数详细信息请参考: ImageMagicK之gravity参数详解
imagemagick的convert命令通过crop参数,可以把一幅大图片分成若干块大小一样的图片,同时也可以在大图上截取一块图片来。命令格式为
convert 原始图片 -crop widthxheight+x+y 目标图片
其中widthxheight是目标图片的尺寸,+x+y是原始图片的坐标点,这两组值至少要出现一组,也可以同时存在。另外该命令也可使用gravity来重新定义坐标系统。关于更多gravity的信息,请参考: ImageMagicK之gravity参数详解。下面介绍几种常用的命令。
convert src.jpg -crop 100x100 dest.jpg 假设src.jpg的大小是300x200,执行命令后将得到名为dest-0.jpg、dest-1.jpg...dest-5.jpg 的6张大小为100x100的小图片。注意如果尺寸不是目标图片的整数倍,那么右边缘和下边缘的一部分图片就用实际尺寸
convert src.jpg -crop 100x80+50+30 dest.jpg 在原始图片的上距离上部30像素左部50为起点的位置,分别向左向下截取一块大小为100x80的图片。如果x相对于坐标,宽度不够100,那就取实际值。 convert src.jpg -gravity center -crop 100x80+0+0 dest.jpg 在原始图上截取中心部分一块100x80的图片 convert src.jpg -gravity southeast -crop 100x80+10+5 dest.jpg 在原始图上截取右下角距离下边缘10个像素,右边缘5个像素一块100x80的图片
利用ImageMagicK的convert命令,能很方便的实现图片的放大缩小,可以进行等比例缩放,也能缩放到指定的固定大小。缩放的参数resize,由它来指定缩放后图片的宽高,比如“200×100”。
注意:虽然明确指定了图片大小为200×100,但dest.jpg的不一定就是200×100,因为是等比缩放的,dest.jpg大小取决原始图片比例。假设src.jpg的大小是500×200,那么缩放后dest.jpg的真实大小为200×80,再比如src.jpg的大小是300×200,缩放后的尺寸为150×100。 原则是缩放后的尺寸最少有一个是符合宽或高,且另外一个不能大于指定的参数中对应的宽或高。另外可以通过只指定宽或高的方式来进行缩放。例如:
convert -resize 200 src.jpg dest.jpg 得到图片宽为200,高根据原始图片比例计算而来 convert -resize x100 src.jpg dest.jpg 得到的图片高位100,宽根据原始图片比例计算而来
convert -resize 200x100! src.jpg dest.jpg
说明:区别是宽高后面多了一个叹号,此时不管原图片比例如何,缩放后的图片大小都是200×100,这样就可能导致图片变形。注意:在linux环境对参数需要用单引号引起来,而windows下又不能使用单引号。
convert -resize "200x100>" src.jpg dest.jpg 注解:只有当src.jpg的宽大于200或高大于100时候,才进行缩小处理, 否则生成的dest.jpg和src.jpg具有一样的尺寸。 注意在linux下要用单引号替换成双引号,即'200x100>'。 convert -resize "200x100<" src.jpg dest.jpg 注解:只有当src.jpg的宽小于200或高小于100时候,才进行放大处理, 否则生成的dest.jpg和src.jpg具有一样的尺寸。 注意在linux下要用单引号替换成双引号,即'200x100<'
上述两种有条件缩放是按原始图等比例缩放的,也就是对符合条件的图片进行等比缩放。同时有条件缩放也可以与固定大小缩放联合起来用。例如如下命令。
convert -resize "800x100>!" src.jpg dest.jpg 注解:假设src.jpg尺寸是300x200。很显然src.jpg的高(200)是大于指定值高(100), 符合缩小的条件,由于执行的不是等比缩放, 所以dest.jpg的尺寸理论上是800x100,由于执行是缩小操作 显然800是超过原始图片宽的,故dest.jpg的宽只能是300 convert -resize "10x1000<!" src.jpg dest.jpg 注解:假设src.jpg尺寸是300x200,src.jpg的高(200)小于指定值高(1000), 因此该命令将执行放大图片操作,dest.jpg的高将放到到1000, 由于目标图片宽比原始图片还小,但是执行的是放大操作,因此只能用原始图片的宽, 所以得到的dest.jpg的尺寸是300x1000。
现在很流行给自己网站的图片加上水印,水印可能是文字,也可能是网站的logo等。图片水印比较简单,就是把自己水印图标合成到原始图片上;文字水印中如果字符包含中文,处理就稍微麻烦一些。
假设把名为logo.gif的水印图标添加在原始图片(src.jpg)右下角,且水印的下边缘距原始图片10像素、右边缘距原始图片5像素。使用如下命令即可:
convert src.jpg logo.gif -gravity southeast -geometry +5+10 -composite dest.jpg
如果不含中文字符,可以直接通过convert draw text的方式将文字添加到图片,否则就需要使用其它的办法。命令行中不能包括中文字符,但是能通过读取文件的方式来操作,即先把中文信息保存文本文件中。 注意:文本文件的编码最好用UTF-8,同时也需要选取一个支持中文的字体。直接把文本文本中的信息输出到图片上使用命令 mogrify,不过也可以使用convert命令把文本文件中的信息生成一个图片,然后再把图片合成到原始图片中。下面分别介绍这几种方法。
convert src.jpg -gravity southeast -fill black -pointsize 16 -draw "text 5,5 'http://www.netingcn.com'" dest-c.jpg mogrify -pointsize 16 -fill black -weight bolder -gravity southeast -annotate +5+5 "http://www.netingcn.com" src.jpg
说明:上述两条命令达到同样的结果,但是第一次命令可以保留原始图片,第二条是直接在原始图片上打上水印。
方法1: //把文件t.txt中的信息生成图片txt.png, -transparent white让图片的背景透明,-size x30设置图片的高度 convert -transparent white -font msyh.ttf -fill black -pointsize 24 label:@t.txt txt.png //把txt.png合成到src.jpg上 convert src.jpg txt.png -gravity southeast -geometry +10+5 -composite dest.jpg 方法2: convert src.jpg -transparent white -font msyh.ttf -fill black -pointsize 24 -size x30 label:@t.txt -gravity southeast -geometry +10+5 -composite dest.jpg 方法3: mogrify -font msyh.ttf -pointsize 24 -fill black -weight bolder -gravity southeast -annotate +20+20 @"t.txt" src.jpg
说明:上述第一、二种方法都有瑕疵,第二种背景不能变成透明,第一种虽然生成的图片可以透明,但是合成到原始图上效果不是很理想,第三种是完全透明的,所以推进用第三种方式来操作。
使用gravity重新定义坐标后,可以很容易让子元素与父元素的对齐方式达到想要的效果,让一切变得非常简单。比如把一张小图片叠加到背景图片的正中位置,按照默认的坐标系统,那必须要先知道背景图片和小图片的宽度以及高度,然后才能计算出起始点的坐标,再通过-geometry来设置坐标点。如果使用gravity,把其设置center,即把中心作为坐标的原点,那么根本不需要计算起始坐标点,ImageMagicK会自动把小图片放置在背景的正中央位置,-geometry默认是+0+0。gravity不仅影响父元素的坐标系统 ,而且子元素的重心点(或者叫参照点)也随之改变。举例来说,当gravity值为southeast,父元素的坐标原点变为右下角了,x轴方向是从右到左,y轴方向从下到上;子元素重心点也是右下角,所以geometry设置的坐标点就是子元素的右下角相对父元素右下角的位置。 gravity会影响通过geometry、annotate、region等来定义坐标点。
gravity可用值有九个,分别是:
说明:创建一个灰色的400×120的背景,分别把两个100×50的小图片放置在背景上的(10,10)和(110,60)的位置,同时通过draw在图片输入一段文本,小图片和文本的参照点是左上角,效果如下图。
convert通过draw可以在已有的图片上绘制一些文字、线条、形状等。可能会用text、line、rectangle、roundRectangle、circle、ellipse等,下面逐一来说明。
convert -size 512x50 xc:gray -gravity southeast -fill red -pointsize 24 -draw "text 20,5 'hello netingcn.com!'" txt.png
上述命令中使用gravity来重新定义坐标,关于gravity的更多信息,请参考 ImageMagicK之gravity参数详解,-fill 设置文字的颜色,颜色能够使用类似#ff00ff的方式,但是需要用双引号引起来,-pointsize 24设置文字的大小, -draw 后面引号中第一个单词是text,表明是在图片上绘制一个设置的文本,20是x坐标,5则是y坐标,hello netingcn.com!是绘制到图片上的文本信息,如果文本信息中含有空格,需要用单引号引起来,没有空格也可以用单引号,所以建议总是使用单引号。 不过遗憾的是不能把中文通过这种方式绘制到图片,要把中文加在图片是,需要另外的方法。结果如下图:
convert -size 512x50 xc:gray -stroke white -strokewidth 4 -draw "line 10,25 500,25" line.png
convert -size 150x150 xc:gray -stroke red -strokewidth 2 -fill white -draw "Rectangle 10,10 140,140" rect-1.png convert -size 150x150 xc:gray -stroke red -strokewidth 2 -fill white -draw "roundRectangle 10,10 140,140 8,8" rect-2.png
说明:参数-stroke 来指定边框的颜色,-strokewidth 指边框的宽度,-fill 矩形的填充颜色,可以用none设置为不填充任何颜色,如果没有-fill参数,默认填充为黑色,Rectangle 与roundRectangle 后第一组参数是确定矩形左上角的坐标,第二组是确定右下角的坐标,roundRectangle的第三组参数是确定圆角的幅度,如果是0,0话,就是直角,所以可以直接用roundRectangle 来代替Rectangle 。示例图片如下:
convert -size 140x140 xc:gray -stroke red -strokewidth 2 -fill white -draw "circle 70,70 5,70" circle.png convert -size 140x140 xc:gray -stroke red -strokewidth 2 -fill white -draw "ellipse 70,70 65,65 0,360" ellipse-1.png convert -size 140x140 xc:gray -stroke red -strokewidth 2 -fill white -draw "ellipse 70,70 60,30 0,360" ellipse-2.png convert -size 140x140 xc:gray -stroke red -strokewidth 2 -fill white -draw "ellipse 70,70 60,30 90,270" ellipse-3.png
说明:同矩形一样,参数-stroke 来指定边框的颜色,-strokewidth 指边框的宽度,-fill 矩形的填充颜色,可以用none设置为不填充任何颜色。circle和ellipse中的第一组参数都是代表圆心的坐标,但是他们第二组参数含义不同,circle的第二组参数是圆的任何一边缘坐标,所以圆的半径就是两组坐标的距离,ellipse的第二组参数中的第一个是横向的最大长度、第二个是纵向最大高度,第三组参数是绘制的区间,区间是0~360度,0度是原点开始到从左到右,度数是顺时针方向。有了这个参数就可以很容易绘制半圆,1/4圆,乃至圆的任何一部分,所以ellipse比circle的功能更加强大。上述的第二条命令完成和第一条命令同样的事。示例图片如下:
gif动画由一系列图片按照一定的时间间隔来播放的,每张单独的图片作为gif动画的一帧。使用ImageMagicK的convert命令很容易获取gif动画中的每桢图片,例如命令 ?convert exam.gif p.png ,?就会把生产 p-0.png,p-1.png 等一系列图片。gif动画的原理就是把一些列动画合成在一起。所以通过convert很容易做到。例如命令 convert *.jpg ?dest.gif ,?是把当前目录下的所有 jpg格式的图片生成一个名为dest.gif的文件,有两个参数比较重要,分别是-delay和-loop,其中-delay是控制每桢的切换时间,-loop是控制gif动画的播放次数,默认是0,0表示无尽的循环播放。
如果想控制每桢的间隔时间不一致,可以使用类似? convert -delay 50 0.jpg 1.jpg -delay 100 2.jpg 3.jpg 4.jpg dest.gif 这样的操作来完成,甚至可以先制作两个临时的gif,然后把临时的gif合成自己想要的,例如
convert -delay 50 0.jpg 1.jpg t1.gif convert -delay 100 2.jpg 3.jpg 4.jpg t2.gif convert t1.gif t2.gif dest.gif
convert -size 84x200 xc:"#f396eb" bg.gifconvert bg.gif logo.gif -geometry +2+2 -composite bg.gif convert bg.gif 0.jpg -geometry +2+55 -composite 0.png convert bg.gif 1.jpg -geometry +2+55 -composite 1.png convert bg.gif 2.jpg -geometry +2+55 -composite 2.png convert bg.gif 3.jpg -geometry +2+55 -composite 3.png convert bg.gif 4.jpg -geometry +2+55 -composite 4.png convert -delay 50 *.png dest1.gif
说明:思路是先创建一张空白背景图片,然后把logo合成在背景上,再依次把素材的每张图片和背景生成一张新图片作为gif动画的一帧,最后使用convert把每桢图片合成一张gif 。这样的缺点是生成的gif图片尺寸会比较大,下面的方法能改进在尺寸上的缺点,但是在gif的循环上又有点不足。
convert -delay 50 *.jpg t.gif convert -size 84x200 xc:"#f396eb" bg.gif convert bg.gif logo.gif -geometry +2+2 -composite bg.gif convert -loop 0 bg.gif -page +2+55 t.gif dest2.gif
ImageMagicK能方便的把多张小图片合成一张大图片。合成的方式大致有三种,
其中方式1处理图片只能左右或上下来拼接图片,方式2最为灵活,可以一次性把多张图片合成在一起,方式3处理多张图片时需要一张一张来处理。下面的例子是把google地图中的4个256×256块合成一张512×512的大图,原始图片如下:
convert +append u0.png u1.png u.png convert +append d0.png d1.png d.png convert -append u.png d.png dest.png
说明:其中 +append 横向把多张图片拼接在一起,可以多于2张,图片按上边缘对齐,最后一个参数是目标图片,而-append是纵向拼接图片,图片按左边缘对齐。
convert -size 512x512 -strip -colors 8 -depth 8 xc:none u0.png -geometry +0+0 -composite u1.png -geometry +256+0 -composite d0.png -geometry +0+256 -composite d1.png -geometry +256+256 -composite dest4.png
说明:convert -size 512×512 xc:none 创建一张空白图片,然后把小图片合成到其上面。合成的命令大致为:convert 背景图片 图片 定义坐标原点 图片的位置 -composite 目标图片,其中“图片 定义坐标原点 图片的位置 -composite” 可以重复,从而把多张图片一次性合成到背景图片上。使用 -gravity 定义坐标原点,默认是左上角,可以用east,north,northwest等来重新定义原点,-geometry相对于原点的位置
convert -size 512x512 -strip -colors 8 -depth 8 xc:none dest1.png composite -geometry +0+0 u0.png dest1.png dest1.png composite -geometry +256+0 u1.png dest1.png dest1.png composite -geometry +0+256 d0.png dest1.png dest1.png composite -geometry +256+256 d1.png dest1.png dest1.png
说明: composite 定义坐标原点 图片的位置 图片 背景图片 目标图片