基于jquery和mini_magick的图片裁剪
jquery imgAeraSelect插件地址:http://odyniec.net/projects/imgareaselect/
原理很简单,就是将鼠标框住的区域两个定点坐标值传回服务器端,在服务器端用image magick处理。
由于rmagick存在内存泄露问题。这里选择了mini_magick。mini_magick是一个非常小的库,源代码不过300行。主要是通过调用系统命令行来处理图片。只要系统安装了image magick就可以。
view:主要是加四个隐藏域来传递裁剪区域。在form提交时候一起传递到服务器。
- <input id="x1" type="hidden" value="0" name="x1"/>
- <input id="y1" type="hidden" value="0" name="y1"/>
- <input id="x2" type="hidden" value="150" name="x2"/>
- <input id="y2" type="hidden" value="150" name="y2"/>
<input id="x1" type="hidden" value="0" name="x1"/>
<input id="y1" type="hidden" value="0" name="y1"/>
<input id="x2" type="hidden" value="150" name="x2"/>
<input id="y2" type="hidden" value="150" name="y2"/>
初始化裁剪框在待处理图片的中央和一些验证:
- <script type="text/javascript">
- $(document).ready(function(){
- var pos = initValue();
- $('#avatar').imgAreaSelect({aspectRatio: '1:1',
- x1: pos.x1,
- y1: pos.y1,
- x2: pos.x2,
- y2: pos.y2,
- handles: true,
- onSelectEnd: function (img, selection) {
- $('input[name=x1]').val(selection.x1);
- $('input[name=y1]').val(selection.y1);
- $('input[name=x2]').val(selection.x2);
- $('input[name=y2]').val(selection.y2);
- }
- });
- });
- function initValue(){
- var o = new Object();
- var x = $("#avatar").width();
- var y = $("#avatar").height();
- var size = x >= y ? y : x;
- size = size >= 100 ? 100 : size;
- o.x1 = (x - size) / 2;
- o.y1 = (y - size) / 2;
- o.x2 = o.x1 + size;
- o.y2 = o.y1 + size;
- return o;
- }
- function checkImage(){
- var image_name = $("#photo").val();
- var reg = /\.png|jpeg|jpg|bmp|gif$/i
- if (reg.test(image_name)){
- return true;
- }else if(image_name == "") {
- alert("没有选择图片!");
- return false;
- }else{
- alert("图片格式不正确!");
- return false;
- }
- }
- </script>
<script type="text/javascript"> $(document).ready(function(){ var pos = initValue(); $('#avatar').imgAreaSelect({aspectRatio: '1:1', x1: pos.x1, y1: pos.y1, x2: pos.x2, y2: pos.y2, handles: true, onSelectEnd: function (img, selection) { $('input[name=x1]').val(selection.x1); $('input[name=y1]').val(selection.y1); $('input[name=x2]').val(selection.x2); $('input[name=y2]').val(selection.y2); } }); }); function initValue(){ var o = new Object(); var x = $("#avatar").width(); var y = $("#avatar").height(); var size = x >= y ? y : x; size = size >= 100 ? 100 : size; o.x1 = (x - size) / 2; o.y1 = (y - size) / 2; o.x2 = o.x1 + size; o.y2 = o.y1 + size; return o; } function checkImage(){ var image_name = $("#photo").val(); var reg = /\.png|jpeg|jpg|bmp|gif$/i if (reg.test(image_name)){ return true; }else if(image_name == "") { alert("没有选择图片!"); return false; }else{ alert("图片格式不正确!"); return false; } } </script>
后台处理,主要就是做以下几件事情:
1.把上传来的照片压缩到200x200
2.通过content-type判断图片是否合法。以防用户自己改扩展名。
3.把gif和png格式转换成jpg,不然在裁剪时候后出问题。
4.裁剪
5.把裁剪后图片缩放成几种比例
- def upload_avatar
- if request.post?
- avatar_200_200 = RAILS_ROOT + "/public/files/avatar/200_200/"
- photo_name = "#{current_user.hash_id}.jpg"
- avatar_100_100 = RAILS_ROOT + "/public/files/avatar/100_100/"
- avatar_64_64 = RAILS_ROOT + "/public/files/avatar/64_64/"
- avatar_50_50 = RAILS_ROOT + "/public/files/avatar/50_50/"
- avatar_40_40 = RAILS_ROOT + "/public/files/avatar/40_40/"
- if params[:commit] == "上传照片"
- #TODO Validate Image Size!
- #TODO 增加白色背景,以防不规则图片!
- photo = params[:photo]
- raise "image type Error!" if photo.content_type !~ /^image\/.*?jpeg|jpg|png|bmp|gif$/i
- Dir.chdir avatar_200_200
- img = MiniMagick::Image.from_blob(photo.read)
- img.format("jpg") if photo.content_type =~ /gif|png$/i
- img.resize "200x200"
- img.write photo_name
- redirect_to request.referer
- elsif params[:commit] == "保存设置"
- Dir.chdir avatar_200_200
- if File.exist?(photo_name)
- width = params[:x2].to_i - params[:x1].to_i
- height= params[:y2].to_i - params[:y1].to_i
- img = MiniMagick::Image.open(photo_name)
- img.crop "#{width}x#{height}+#{params[:x1]}+#{params[:y1]}"
- img.resize 100 and Dir.chdir avatar_100_100 and img.write photo_name
- img.resize 64 and Dir.chdir avatar_64_64 and img.write photo_name
- img.resize 50 and Dir.chdir avatar_50_50 and img.write photo_name
- img.resize 40 and Dir.chdir avatar_40_40 and img.write photo_name
- end
- end
- end
- end
def upload_avatar
if request.post?
avatar_200_200 = RAILS_ROOT + "/public/files/avatar/200_200/"
photo_name = "#{current_user.hash_id}.jpg"
avatar_100_100 = RAILS_ROOT + "/public/files/avatar/100_100/"
avatar_64_64 = RAILS_ROOT + "/public/files/avatar/64_64/"
avatar_50_50 = RAILS_ROOT + "/public/files/avatar/50_50/"
avatar_40_40 = RAILS_ROOT + "/public/files/avatar/40_40/"
if params[:commit] == "上传照片"
#TODO Validate Image Size!
#TODO 增加白色背景,以防不规则图片!
photo = params[:photo]
raise "image type Error!" if photo.content_type !~ /^image\/.*?jpeg|jpg|png|bmp|gif$/i
Dir.chdir avatar_200_200
img = MiniMagick::Image.from_blob(photo.read)
img.format("jpg") if photo.content_type =~ /gif|png$/i
img.resize "200x200"
img.write photo_name
redirect_to request.referer
elsif params[:commit] == "保存设置"
Dir.chdir avatar_200_200
if File.exist?(photo_name)
width = params[:x2].to_i - params[:x1].to_i
height= params[:y2].to_i - params[:y1].to_i
img = MiniMagick::Image.open(photo_name)
img.crop "#{width}x#{height}+#{params[:x1]}+#{params[:y1]}"
img.resize 100 and Dir.chdir avatar_100_100 and img.write photo_name
img.resize 64 and Dir.chdir avatar_64_64 and img.write photo_name
img.resize 50 and Dir.chdir avatar_50_50 and img.write photo_name
img.resize 40 and Dir.chdir avatar_40_40 and img.write photo_name
end
end
end
end
效果预览:
来源:http://www.iteye.com/topic/541141