用网页做了一个拼图的小工具。
需求:自己生活中遇到的问题。截图,一共6张。对每张图片:编辑,旋转,保存,这一阶段大约需要18次操作。对3张图片:相册 -> 推荐 -> 拼图 -> 选择拼图-> 拼接。拼接的结果旋转。一共6张,3张一组,一共两组,大致需要22次操作。这两组得拼完再旋转得到想要的结果。至少48次操作,能不能做个工具?简化一下?输入六张图,按个按钮得到拼好的一张图?
尝试:安卓应用?网页?小程序?图片是私人物品,小程序以微信为基础,私人物品经过微信感觉不安全。在安卓和网页纠结了一段时间,安装调试安卓环境花费近2小时。后来用网页做着做着就做出来了!
实现思路:
使用input的type属性为file的表单控件(以下简称控件)从手机获取图片:控件的change事件表示图片选择完了。
把图片放到canvas画布(以下简称画布或canvas)处理:获取file对象。input.files[0]获取控件图片对应的file对象。使用file对象建立fileReader对象,获取文件本身。使用fileReader对象建立img对象。canvas画笔的drawImage方法使用img对象就能在canvas上画图了。
reader.onload什么意思?图片读取成功。img.onload什么意思?图片加载完成。不把代码写在onload的方法里可能没效果,因为onload执行的方法大概是异步方法。
导出处理的图片不难。电脑可以直接在画布上右键另存图片。至此,PC端使用浏览器处理图片实现了。安卓手机对img标签长按图片可以另存为(夸克浏览器 V 4.2.0.137不行,小米浏览器 V 16.2.16行)。canvas的toDataURL方法可以把canvas内容当图片输出,等号左边是img标签的href属性,右边是toDataURL方法即可。如下图。至此,安卓端用浏览器处理图片完成了。
=============核心内容结束============================
开发过程遇到的问题和思路
上传文件的类型和图片类型不一致
read的对象以readAsDataURL方式读取成功后,result属性能当src的值。
https://www.cnblogs.com/zimengxiyu/p/11359053.html#:~:text=js%E4%B8%8A%E4%BC%A0%E5%9B%BE%E7%89%87%20%E5%89%8D%E7%AB%AF%E4%B8%8A%E4%BC%A0%E5%9B%BE%E7%89%87%E7%9A%84%E5%8E%9F%E7%90%86%E6%98%AF%EF%BC%9A%E8%BF%90%E7%94%A8input,type%3D%E2%80%9Cfile%E2%80%9D%E7%9A%84%E6%A0%87%E7%AD%BE%E8%8E%B7%E5%8F%96%E5%9B%BE%E7%89%87%EF%BC%8C%E5%86%8D%E4%BD%BF%E7%94%A8FileReader%E8%BF%99%E4%B8%AA%E5%AF%B9%E8%B1%A1%20new%20%E4%B8%80%E4%B8%AA%E5%AE%9E%E4%BE%8B%EF%BC%8C%E9%80%9A%E8%BF%87%E8%BF%99%E4%B8%AA%E5%AF%B9%E8%B1%A1%E7%9A%84readAsDataURL%28%29%E6%96%B9%E6%B3%95%E8%AF%BB%E5%8F%96file%E6%A0%87%E7%AD%BE%E8%8E%B7%E5%8F%96%E7%9A%84%E5%9B%BE%E7%89%87%E5%B9%B6%E8%BD%AC%E6%8D%A2%E4%B8%BAbase64%E6%A0%BC%E5%BC%8F%EF%BC%8C%E5%AE%8C%E6%88%90%E4%B9%8B%E5%90%8E%E9%80%9A%E8%BF%87ajax%E4%B9%8B%E7%B1%BB%E7%9A%84%E6%96%B9%E5%BC%8F%E4%BC%A0%E5%88%B0%E5%90%8E%E5%8F%B0%E3%80%82
至此,表单上传图片,在img标签显示已经成功了。
//获取图片输入流
let reader = new FileReader();
//reader.readAsArrayBuffer(person1Picture1.files[0]);
reader.readAsDataURL(person1Picture1.files[0]);
reader.onload = function() {
alert("人1图片1:读取成功");
imgp1p1.src = reader.result;
console.log(reader.result);
//myCanvas2DContext.drawImage(new File(reader.result, "imgp1p1"), 0, 0);
}
reader.onerror = function() {
alert("人1图片1:读取失败");
}
canvas图片可以直接另存为
保存的图片大小为整个画布大小。
在电脑上能右键保存,手机不行。可以把canvas内容画到Img里。
表单上传图片画到canvas上。
https://segmentfault.com/a/1190000007237076
img对象
这样就明白img.onload方法是干啥的了。
https://blog.csdn.net/WARGON/article/details/83785188
获取img对象宽高
https://blog.csdn.net/weixin_42448623/article/details/106329904?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1-106329904-blog-83785188.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1-106329904-blog-83785188.pc_relevant_default&utm_relevant_index=2
canvas画布动态调整大小
设置画布宽高即可。
为什么我第一次设置宽高没效果?因为设置的是上下文的宽高,不是画布的宽高。但是不报错。
把非基本类型的对象放数组里,取出来的元素的类型是object
但好像放数组和map里都行。
for(let fileTemp of document.getElementById("filesForm").children) {
console.log(`id: ${fileTemp.id}`);
}
imgWidth
console.log(imgWidth);
console.log(imgHeight);
console.log(`canvas height: ${myCanvas.height}, canvas ${myCanvas.width}`);
console.log(`image height: ${imgHeight}, image ${imgWidth}`);
画图规律研究
0 1 2
3 4 5
0 1 2 的y 是0, 3 4 5 的y 是height,0 1 2的 x 是width * i, 3 4 5 的x 是width * (i - 3)。
导出图片
尝试解决手机无法复制canvas图片的问题。
方案1 img标签显示图片
手机复制失败。
手机可以长按保存图片,夸克保存失败
实现方法:canvas结果做Img标签src属性的值。
https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLCanvasElement/toDataURL
方案2 保存到剪贴板
方案3 下载
a标签能下载。
遇到问题:为什么我通过a标签下载的图片只有6KB或7KB?因为没有数据。数据填进src属性里了,本应是href属性,更改后好了。
夸克浏览器4.2.0.137不支持a标签下载。。。小米浏览器不支持。。
写字
两种方案。一种是绘制文字,另一种方案是插入文字图片。
https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial/Drawing_text