这几天折腾把前端旋转后的图片在后端合成出来。遇到一些问题。
这里有2种解决办法:
方法一:
使用canvas,在画布里面旋转并在客户端合成图片转换成base64到服务器即可,但是这样做有个很大的问题就是图片文件很大的时候提交得半天,而且浏览器post数据是有大小限制的。并且项目里面已经用到了SVG,混合使用可能坑比较多,暂时没有考虑。
方法二:
前端使用transform: rotate把角度传回服务器通过GD库合成图片。因为要旋转的图片是已知并存在于服务器端的所以不存在需要提交图片数据的问题。
服务器端主要用到了GD的imagerotate方法,这里就遇到了几个坑:
1、图片旋转后空白区域变成了黑色如图右下角,解法:把一个透明画布传入方法
public function pic_rotating($degrees,$url){
$srcImg = imagecreatefrompng($url); //获取图片资源
$pngTransparency = imagecolorallocatealpha($srcImg, 0, 0, 0, 127);
imagefill($srcImg, 0, 0, $pngTransparency);
$rotate = imagerotate($srcImg, -1*$degrees, $pngTransparency); //原图旋转
return $rotate;
}
2、旋转后图片被缩放了,可以对比前端和后端的图片,这个就很坑了,这里确实可以用三角函数重新算图片尺寸,但是我的项目一张图里面可能一次要合成很多张,之前在GD里面也是领教过各种坑的,所以知难而退,打算在前端想办法。其实这个问题在前端是不用算的,虽然图片旋转后脱离的文档飘在页面上,但是html里面的元素不管你做什么操作在文档里面都是矩形的,这里要用到的方法是getBoundingClientRect。那么这个办法刚好可以低成本计算出GD旋转保持图片不缩放的大小和坐标。
3、imagerotate旋转后的图片总喜欢丢失边上的一部分像素,这个我的解法是把要旋转的源图像不做满四周留点空白。
最后实现的效果(宝石图片清晰度不够- -!),前端:
服务器合成图: