公司年前要推一个制作新年贺卡的H5活动页,开发过程中踩了几个坑,今天总结分享一下。
最初方案:将用户图片上传服务器,返回url显示在页面上,点击生成贺卡按钮,将url以及贺卡昵称、祝福语传给接口,后台返回一张生成贺卡图片url,显示在页面上,用户可长按保存。
出现的问题:ios多个型号的手机出现拍照或者相册上传的图片会自动旋转90度,用户不可自己选择裁剪区域。
最终方案:使用jQueryphotoClip图片剪裁插件,用户可手动缩放、旋转图片,并选择裁剪区域。
使用要点:
1.引入依赖的插件( 注意引入的先后顺序 )
<script type='text/javascript' src='../js/photoClip/hammer.js'></script>
<script type='text/javascript' src='../js/photoClip/iscroll-zoom.js'></script>
<script type='text/javascript' src='../js/photoClip/lrz.all.bundle.js'></script>
<script type='text/javascript' src='../js/photoClip/jquery.photoClip.js'></script>
2.参数配置
<div id="clipArea"></div>
<input type="file" id="file">
<button id="clipBtn">截取</button>
<div id="view"></div>
<script>
var clipArea = new bjj.PhotoClip("#clipArea", {
size: [260, 260], // 截取框的宽和高组成的数组。默认值为[260,260]
outputSize: [640, 640], // 输出图像的宽和高组成的数组。默认值为[0,0],表示输出图像原始大小
//outputType: "jpg", // 指定输出图片的类型,可选 "jpg" 和 "png" 两种种类型,默认为 "jpg"
file: "#file", // 上传图片的<input type="file">控件的选择器或者DOM对象
view: "#view", // 显示截取后图像的容器的选择器或者DOM对象
ok: "#clipBtn", // 确认截图按钮的选择器或者DOM对象
loadStart: function(file) {}, // 开始加载的回调函数。this指向 fileReader 对象,并将正在加载的 file 对象作为参数传入
loadComplete: function(src) {}, // 加载完成的回调函数。this指向图片对象,并将图片地址作为参数传入
loadError: function(event) {}, // 加载失败的回调函数。this指向 fileReader 对象,并将错误事件的 event 对象作为参数传入
clipFinish: function(dataURL) {}, // 裁剪完成的回调函数。this指向图片对象,会将裁剪出的图像数据DataURL作为参数传入
});
</script>
3.裁剪成功
裁剪成功后,可在loadComplete回调函数中拿到src参数(base64格式的图片地址),对裁剪后的图片再做进一步操作。
本次开发过程中,最初设置outputSize尺寸为后台生成图片时所需的图片大小(生成图片时,图片大小要固定,不能进行缩放),后因为图片模糊,将尺寸设置为[0,0],然后用PHP将图片压缩至所需尺寸,再将祝福语、昵称、用户图共同合成贺卡图片。代码如下:
public function getResult()
{
$img_url = _pv('img_url') ? _pv('img_url') : "";
$name = _pv('name') ? _pv('name') : "";
$content = _pv('content') ? _pv('content') : "";
if (!$img_url || !$name || !$content){
_ars("缺少参数",false);
}
if (preg_match('/^(data:\s*image\/(\w+);base64,)/',$img_url,$res)){
$extension = $res[2];
}else{
$extension = "jpg";
}
if (strstr($img_url,",")){
$image = explode(',',$img_url);
$image = $image[1];
}
$filename = "/tmp/".time().rand(0,200).".".$extension;
$bgImgPath = "./kz-element/newyearcard.jpg"; //背景图地址
$font = './kz-element/sybold.ttf';
$font2 = './kz-element/syhtnormal.ttf';
$source = fopen($filename,'w');
$saveRes = fwrite($source,base64_decode($image));
fclose($source);
if (!$saveRes){
_ars("生成失败,请稍后重试~",false);
}
//对用户上传的图片进行大小处理
$res = $this->resizeImg($filename,510,302);
if (!$res){
_ars("生成失败,请稍后重试~",false);
}
$im = createImgByType($bgImgPath);
$user_im = createImgByType($filename);
if (!$im || !$user_im){
_ars("生成失败,请稍后重试~",false);
}
//图片放置位置和大小
$marginRight = 123;
$marginBottom = 623;
$width = 510;
$height = 302;
imagecopymerge($im,$user_im,imagesx($im) - $width - $marginRight,imagesy($im) - $height - $marginBottom,0,0,$width,$height,100); //放图完毕
//写字
$to = $this->filterEmoji($name)."祝您 :";
$color = imagecolorallocate($im,156,0,14);
imagettftext($im, 22, 0, 118, 772, $color, $font,$to);
$content = $this->filterEmoji($content);
mb_strlen($content) > 54 && $content = mb_substr($content,0,54) . "...";
$length = mb_strlen($content);
$block = (int)($length / 19) + 1; //19个字一行
for ($i = 0;$i < $block;$i++){
$text = mb_substr($content,$i*19,19);
imagettftext($im, 20, 0, 118, 825 + $i*32, $color, $font2,$text);
}
$resFileName = md5(time()).".png";
$respath = '/opt/htdocs/upload/goodsrcode/'.$resFileName;
$res = imagepng($im,$respath);
imagedestroy($im);
imagedestroy($user_im);
@unlink($filename);
if ($res){
_ars(SUPERMAN_IMG_HOST.'/upload/goodsrcode/'.$resFileName,true);
}
_ars("error",false);
}
public function resizeImg($path,$width = 510,$height = 302)
{
$imgInfo = getimagesize($path);
$im = createImgByType($path);
if (empty($imgInfo) || !$im){
return false;
}
$img_width = $imgInfo[0];
$img_height = $imgInfo[1];
$source_ratio = $img_width/$img_height;
$src_width = $src_height = 0;
$des_height = $height;
//计算缩放比例
if(($width/$img_width)>($height/$img_height)){
$b=$height/$img_height;
}else{
$b=$width/$img_width;
}
//计算出缩放后的尺寸
$nw=floor($img_width*$b);
$nh=floor($img_height*$b);
$temp_img = imagecreatetruecolor($nw , $nh);//创建画布
$white = imagecolorallocate($temp_img, 255, 255, 255);
imagefill($temp_img, 0, 0, $white);
imagecopyresampled($temp_img,$im,0,0,0,0,$nw,$nh,$img_width,$img_height);
$res = buildImgType($temp_img,$imgInfo[2],$path);
imagedestroy($im);
return true;
}
更多jQueryphotoClip相关内容:http://www.jq22.com/jquery-info7428
新年贺卡H5活动页面:https://m.douguo.com/activity/newyearcard