html5头像裁剪,H5头像裁剪的实现与坑位

最近有个需求,需要在H5上实现用户头像裁剪。需求如下:

9923ee66a7fdd3cf55a2cc4bc40e4223.png

1.穿透效果的透明蒙层

使用canvas的ctx.globalCompositeOperation='destination-out'实现。

(该特性还可以实现类似刮刮乐的效果)

ef5f52ff6c81ed768c983b43fe6d1980.png

坑位1:在一些高分辨率的安卓机子上,绘制canvas图形会出现模糊的现象。因为canvas元素依赖于设备像素比,所以适配高清屏,canvas内容的宽高需要设置为实际的宽高的dpr倍。但是如果这么设置会导致画面空白一片,无法显示。

10334b434fea2f5c0ed06c8b9e7acf61.png

2.可平移缩放的图片显示器

510c389ca92eb6b3fcb6e7904064045a.png

a3f20e45c62e32bb87313dddbbfc8b4f.png

坑位2:在做安卓平板兼容时,有时候多点触摸操作后,再进行单点触摸,touch事件返回的touchList不是只有一个触摸点的信息,也会有多个触摸点的信息。导致依赖触摸点去判断平移还是缩放操作的准则失效。

解决方法:发现如果多点触摸后再单点触摸,如果touchList的长度不为1时,touch[0]之后的触摸点的位置都是维持不变的,只有touch[0]的位置坐标会发生变化,因此利用此点来追加判断单点触摸还是多点触摸。

3.图片裁剪编辑器

57bed1eb89cc3ef5fee19237d9f8a270.png

188ae5f184fdc1cf144a608da78420e8.png

坑位3:利用屏幕显示的图片尺寸,去进行裁剪,怎么裁剪都不对。

解决方法:裁剪操作的图片大小并不是在屏幕上显示的图片大小,而是源图片的大小。需要使用element.naturalWidth和element.naturalHeight属性来正确计算裁剪和缩放区域等内容,而不是element.width和element.height。

2590defe4a13a9e0275ec82a4bb6e3ba.png

坑位4:采用naturalWidth、naturalHeight与width和height的比例来纠正裁剪源图的坐标,在首次加载图片裁剪的效果是正确的,但是二次加载图片裁剪后的效果又是不正确的。

解决方法:不使用element.width和element.heightl来进行源图片与屏幕显示图片的比例换算。是因为当图片有缓存时,首次加载完成的width和height分别与naturalWidth和naturalHeight相等(后面又会恢复正常),width和height获取不到正确的图片屏幕显示尺寸,导致裁剪算法异常。这里使用element.clientWidth和element.clientHeight进行与源图片的比例换算。

坑位5:IOS手机编辑时,显示的图片方向是正确的,但是经过裁剪后,获取的图片不正确。IOS在显示的时候,会根据图片EXIF属性中的orientation值,进行自动旋转纠正图片的显示方向。

90a37f2fd94bd6f3bcc2dfa817994067.png

解决方法:引入一个exif.js的库,获取图片的orientation值,来对图片进行方向旋转的处理。在此只需要处理:1.顺时针旋转90°,2.逆时针旋转90°,3.顺时针旋转180°,三种情况。

d22aaf40e88acb0fca84265ee3fa38af.png

6e0f7e8cfb2eab3d43961d44e370c195.png

921e30c4804c2acd951baa5a82b0cd03.png

e1a3d3dab2517dce12c637cd8dd64769.png

(引入exif.js的代码网上有很多,但是没有具体的旋转分析图,当时这个想了挺久的TOT~)

坑位6:裁剪经过旋转显示的宽度大于屏幕宽度的图片,往往会出现裁剪部分缺失或裁剪出空白的图片,但是裁剪的坐标和宽度经过推算是没有错。

35ccd562cb803e47a4d7c8d0c645b5fb.png

ae5f93a575b70659480ac577cd07055a.png

解决方法:屏幕上加载显示的图片,并非缓存中的原图片经过旋转缩放获取,如果image图片的style限定了宽度和高度,那么缓存中的原图片加载的宽度和高度会受此限制。因此需要另外加载一个没有宽高样式限制的图片作为裁剪的源图片。

坑位7:高度小于裁剪高度时,会导致裁剪框的参数计算异常。

解决方法:维持裁剪的sX坐标不变,将sY坐标设置为0,裁剪高度和宽度为图片的源高度。

b0feb2099aadc47ba09ea624bdc56edb.png

4.展望

更多可能性的操作,例如图片可旋转的操作,那么裁剪坐标该如何计算。

dc75385fde7a05b9f78cbc59ea5803fa.png

如何简化计算?可以利用线性代数进行运算(两个不同矩阵相乘记得齐次方程处理)。

3c0390104f2b918566b2fb59a9fd779e.png为了便于进行旋转、平移、缩放等混合操作运算,矩阵需要作齐次方程处理。

797b07f1f1570bfb18bf2cabc3730246.png

可以进一步将矩阵的计算抽取为公共工具函数类:

241dec7497f9ac781b76845d219d310e.png

其灵感来自于学习WebGL的矩阵转换运算,笔者也是刚入门学习中,欢迎交流~~

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值