1.出现bug的图片
2.定位问题点:
由于问题是第三方编辑器产生的,所以通过编辑器源码去定位旋转功能代码,再去分析问题产生的原因;
-
项目中引入的编辑器资源源码是经过压缩混淆过的,长这样:
这谁看得懂。。。 然后想着格式化之后再看看;格式化后长这样
这就好多了, 虽然有一些变量被处理了,通过调用的方法大概能猜出来他是个什么对象;
-
开始定位功能点:通过点击的旋转元素的类名 找到代码中有对应类名的地方,然后就找到了这段代码:
- 大概的意思就是:绑定一个imageRotate事件,当事件触发的时候,调用hm实例的execute方法;
- 未旋转元素绑定点击事件,点击时触发imageRotate事件;
- execute方法中处理图片旋转部分代码
- 大概的意思就是 通过canvas的translate、rotate等方法将编辑器中的图片旋转指定的角度后绘制出来,然后将绘制好的图片通过toDataUrl转成指定格式的图片渲染到编辑器中;乍一看源码好像没什么问题,然后我又开始谷歌搜索,发现一篇文章中提到 canvas在转换成jpeg格式的图片时。移除了alpha通道,所以透明区域被渲染成了黑色, 和我的情况完全匹配,我的应该也是这个原因。然后跟着找解决方法,他提到可以先在绘制前使用白色背景填充绘制区域,这样将图片绘制好后导出的图片就是白色的;但我发现编辑器源码里面本身就有这么一段代码;但是展示的效果仍然有黑色区域。。。 但是仔细看黑色区域的部分,他其实上半部分是转换成功了的,只是下半部分没有转换成功;我就想到是不是填充白色的区域计算出了问题,导致只填充了上半部分没填充到下半部分; 然后开始读源码,发现因为要实现旋转,需要将canvas画布进行相应的旋转,旋转完之后,源码中又将原图片的宽度赋值给了画布的高,图片的高度赋值给了画布的宽, 但是在进行旋转的时候,其实包括画布的坐标轴也进行了旋转。所以导致填充白色的区域出现了偏差 变成了这样:
- 这就形成了 上半部分成功,下半部分黑色的情况;所以源码上bug只需要将填充地方的宽高交换一下就可以了;
-
上面是通过填充白色背景来解决问题,但如果我就是要保留原图的透明怎么办呢,这时候只需要将图片转成png的图片就行了。所以这里的最好的解决方法是,在转换图片之前 拿到图片格式,在转换的时候 指定为这个格式就行,都不用去纠结白色填充的问题;
-
总结:
- jpeg格式的图片不支持透明通道。假如有个rgba(0,0,0,0) 色值表示透明,他只认识前三个色值 rgb(0,0,0) 所以将透明变成了黑色;
- Canvas画布在旋转的时候对应的坐标系也会跟着旋转,所以对应的x轴、y轴的值应该不变;