maybe yes 发表于2014-12-12 10:58
原文链接 : http://blog.lmlphp.com/archives/32 来自 : LMLPHP后院
前端使用Jcrop实现预览和获取图片大小,选定位置等信息。关于Jcrop,项目地址在GITHUB上,它基于MIT开源协议。本人看了下项目的源代码,感觉作者蛮认真的。Jcrop做到了兼容IE系列和其他主流浏览器,非常稳定,让开发者不再为前端方面花费太多精力。加上本人不太喜欢Flash实现,纯JavaScript实现的功能效率会更高。由于时间比较仓促,代码没有过多的优化,有点乱,下面公布前端实现和服务端处理图片部分代码。
前端实现方式如下:
<link rel="stylesheet" href=".../jcrop/tapmodo-Jcrop-1902fbc/css/jquery.Jcrop.css"> <script src=".../jcrop/tapmodo-Jcrop-1902fbc/js/jquery.min.js"></script> <script src=".../jcrop/tapmodo-Jcrop-1902fbc/js/jquery.Jcrop.js"></script> <style> #preview-pane{ background-color: white; border: 1px solid rgba(0, 0, 0, 0.4); border-radius: 6px; box-shadow: 1px 1px 5px 2px rgba(0, 0, 0, 0.2); display: none; padding: 6px; position: absolute; right: -160px; top: 0; z-index: 2000; } #preview-pane .preview-container { height: 100px; overflow: hidden; width: 100px; } .cropdiv{ background: none repeat scroll 0 0 #fff; border: 1px solid #ccc; border-radius: 5px; box-shadow: 0 20px 20px rgba(0, 0, 0, 0.3); height: auto; left: 200px; opacity: 0.9; position: absolute; top: 230px; width: 600px; z-index: 100; padding:10px; } .cropdiv .preinfo{ float: right; left: 500px; position: absolute; top: 160px; } .cropdiv .title{ font-size:14px; font-weight:bold; margin-bottom:10px; } .cropdiv .save{ text-align:center; } .cropdiv .save a{ background-color: #ff832b; border-radius: 4px; color: #fff; display: inline-block; height: 30px; padding:2px 5px; font-size:16px; margin:5px; } </style> <script> var startcrop = function( imgsrc ) { var jcrop_api, boundx, boundy, posinfo, imgsrc_rand = imgsrc + '?' + Math.round(Math.random() * 10000); // Grab some information about the preview pane var $preview_html = '<div id="preview-pane">' +'<div class="preview-container">' +'<img src="" class="jcrop-preview" alt="Preview">' +'</div>' +'</div>'; $(document.body).append($preview_html); var $preview = $('#preview-pane'), $pcnt = $('#preview-pane .preview-container'), $pimg = $('#preview-pane .preview-container img'), xsize = $pcnt.width(), ysize = $pcnt.height(); $pimg.attr('src',imgsrc_rand); var cropimgdiv = $('<div/>').addClass('cropdiv').css({"opacity":.9}) .append(function(){ return $('<div/>').append("<span>编辑头像</span>").addClass('title');; }) .append( function(){ return $('<img/>').attr( {"src":imgsrc + '?' + Math.round(Math.random() * 10000) ,"id":"cropimg"}) }) .append(function(){ return $('<div/>').append( $("<a/>").html("保存头像").click(function(){ $.ajax({ type:'POST', url: 'handle crop url', dataType:'json', data:{ 'posinfo':posinfo, "boundx":boundx, "boundy":boundy }, success:function( data ) { // do something on success cropimgdiv.remove(); $preview.remove(); } }); }) ).addClass('save'); }) .appendTo(document.body); if ($("#cropimg").get(0).naturalWidth > 400) { $("#cropimg").attr({"width":400}); JcropRun(); } else { // IE6/7/8 var image = new Image() image.src = imgsrc_rand; image.onload = function(){ if( image.width > 400){ $("#cropimg").attr({"width":400}); } JcropRun(); }; } function showCoords(c) { /* variables can be accessed here as // c.x, c.y, c.x2, c.y2, c.w, c.h*/ posinfo = c; if (parseInt(c.w) > 0) { var rx = xsize / c.w; var ry = ysize / c.h; $pimg.css({ width: Math.round(rx * boundx) + 'px', height: Math.round(ry * boundy) + 'px', marginLeft: '-' + Math.round(rx * c.x) + 'px', marginTop: '-' + Math.round(ry * c.y) + 'px' }); } }; var JcropRun = function(){ $('#cropimg').Jcrop({ onSelect: showCoords, bgColor: 'black', bgOpacity: .4, setSelect: [ 100, 100, 0, 0 ], minSize: [ 100, 100 ], aspectRatio: xsize / ysize },function(){ // Use the API to get the real image size var bounds = this.getBounds(); boundx = bounds[0]; boundy = bounds[1]; // Store the API in the jcrop_api variable jcrop_api = this; $preview.css({"display":"block"}); // Move the preview into the jcrop container for css positioning $preview.appendTo(jcrop_api.ui.holder); }); } }; </script>
imagecropper方法在网上找的,写的比较差,以后有时间会整理下代码。后台图片处理方式如下:
<?php function imagecropper($source_path, $target_width, $target_height) { $source_info = getimagesize($source_path); $source_width = $source_info[0]; $source_height = $source_info[1]; $source_mime = $source_info['mime']; $source_ratio = $source_height / $source_width; $target_ratio = $target_height / $target_width; // 源图过高 if ($source_ratio > $target_ratio) { $cropped_width = $source_width; $cropped_height = $source_width * $target_ratio; $source_x = 0; $source_y = ($source_height - $cropped_height) / 2; } // 源图过宽 elseif ($source_ratio < $target_ratio) { $cropped_width = $source_height / $target_ratio; $cropped_height = $source_height; $source_x = ($source_width - $cropped_width) / 2; $source_y = 0; } // 源图适中 else { $cropped_width = $source_width; $cropped_height = $source_height; $source_x = 0; $source_y = 0; } switch ($source_mime) { case 'image/gif': $source_image = imagecreatefromgif($source_path); break; case 'image/jpeg': $source_image = imagecreatefromjpeg($source_path); break; case 'image/png': $source_image = imagecreatefrompng($source_path); break; default: return false; break; } $target_image = imagecreatetruecolor($target_width, $target_height); $cropped_image = imagecreatetruecolor($cropped_width, $cropped_height); // 裁剪 imagecopy($cropped_image, $source_image, 0, 0, $source_x, $source_y, $cropped_width, $cropped_height); // 缩放 imagecopyresampled($target_image, $cropped_image, 0, 0, 0, 0, $target_width, $target_height, $cropped_width, $cropped_height); /* header('Content-Type: image/jpeg'); */ ob_start(); imagejpeg( $target_image ); return ob_get_clean(); /* imagedestroy($source_image); imagedestroy($target_image); imagedestroy($cropped_image); exit; */ } $boundx = $_POST['boundx']; $boundy = $_POST['boundy']; $posinfo = $_POST['posinfo']; $realimg = '用户上传后的原图地址'; $resizeimg = imagecropper($realimg, $boundx, $boundy); file_put_contents($realimg, $resizeimg); /* 上面完成了图片的大小压缩,下面将图片进行裁剪 */ $source_info = getimagesize($realimg); $source_mime = $source_info['mime']; switch ($source_mime) { case 'image/gif': $source_image = imagecreatefromgif($realimg); break; case 'image/jpeg': $source_image = imagecreatefromjpeg($realimg); break; case 'image/png': $source_image = imagecreatefrompng($realimg); break; default: return false; break; } $target_image = imagecreatetruecolor($posinfo['w'], $posinfo['h']); $cropped_image = imagecreatetruecolor($posinfo['w'], $posinfo['h']); imagecopy( $cropped_image, $source_image, 0, 0, $posinfo['x'], $posinfo['y'], $posinfo['w'], $posinfo['h'] ); imagecopyresampled($target_image, $cropped_image, 0, 0, 0, 0, $posinfo['w'], $posinfo['h'], $posinfo['w'], $posinfo['h']); ob_start(); switch( $source_mime ){ case 'image/gif': imagegif( $target_image ); break; case 'image/jpeg': imagejpeg( $target_image ); break; case 'image/png': imagepng( $target_image ); break; default: return false; } file_put_contents($realimg, ob_get_clean() );
附上运行截图:
阅(38)评(0)查看评论