网站首页 > 技术文章 正文
canvas画图问题
- drawImage()、getImageData()或toDataURL()操作图片时,有时会遇到跨域问题,首先服务器允许跨域的图片基本上都可以drawImage到画布上,但想获取图片信息时,会报跨域问题,增加img.crossOrigin = ''即可,虽然js代码这里设置的是空字符串,实际上起作用的属性值是anonymous.
2. 绘制字体自动换行实现,如何让canvas支持自动换行?原理的核心是measureText(text)这个API,可以用来测量文本的一些数据 ,此方法返回的字符宽度值非常精确,下面就是扩展的文本自动换行方法JS代码:
CanvasRenderingContext2D.prototype.wrapText = function (text, x, y, maxWidth, lineHeight) {
if (typeof text != 'string' || typeof x != 'number' || typeof y != 'number') {
return;
}
var context = this;
var canvas = context.canvas;
if (typeof maxWidth == 'undefined') {
maxWidth = (canvas && canvas.width) || 300;
}
if (typeof lineHeight == 'undefined') {
lineHeight = (canvas && parseInt(window.getComputedStyle(canvas).lineHeight)) || parseInt(window.getComputedStyle(document.body).lineHeight);
}
// 字符分隔为数组
var arrText = text.split('');
var line = '';
for (var n = 0; n < arrText.length; n++) {
var testLine = line + arrText[n];
var metrics = context.measureText(testLine);
var testWidth = metrics.width;
if (testWidth > maxWidth && n > 0) {
context.fillText(line, x, y);
line = arrText[n];
y += lineHeight;
} else {
line = testLine;
}
}
context.fillText(line, x, y);
};复制代码
其中text, x, y 3个参数和fillText()方法中的这3个参数含义是一样的。而maxWidth表示最大需要换行的宽度,此参数可缺省,默认会使用canvas画布的width宽度作为maxWidth;lineHeight表示行高,默认会使用<canvas>元素在DOM中继承的line-height作为行高。 用法很简单,使用wrapText代替原生的fillText即可! 详情=> 张大大
3. 图片画到画布上后,有的电脑会出现画布模糊问题
原因是设备的devicePixelRatio值不同,(该 Window 属性 devicePixelRatio 能够返回当前显示设备的物理像素分辨率与 CSS 像素分辨率的比率。此值也可以解释为像素大小的比率:一个 CSS 像素的大小与一个物理像素的大小的比值。简单地说,这告诉浏览器应该使用多少个屏幕的实际像素来绘制单个 CSS 像素。这在处理标准显示与 HiDPI 或 Retina 显示之间的差异时很有用,它使用更多屏幕像素绘制相同对象,从而产生更清晰的图像。)一些高清屏上会出现画面模糊,解决放法:无论devicePixelRatio值为多少、统一将canvas节点的width属性设置为其csswidth属性的两倍,将height属性也设置为cssheight属性的两倍,因为canvas属性width和css中width表达的含义是不同的,这样整个canvas的坐标系范围就扩大为两倍,但是在浏览器的显示大小没有变,canvas画图的时候,按照扩大化的坐标系来显示,不清晰的问题就得以改善了。
<canvas width="320" height="180" style="width:160px;height:90px;"></canvas>
4、上传图片方向的问题,有时候上传图片是有方向要求的,比如必须上传正向人像照片,这时就需要注意了 ,因为不同手机之间是存在兼容性问题的,这里推荐一个插件,读取图像方向信息 exif.js 一把吧图片信息传给后端后 ,后端会返回你需要的各种方向的图片,
5、 利用canvas实现图片压缩上传,先上代码,解释基本都注释了
//压缩
canvasImg(url,name){
let canva=document.createElement('canvas'),oImg=new Image();
oImg.crossOrigin = '';
oImg.onload=()=>{
//根据原图大小设置画布高最高720,宽最宽1080,小于这个尺寸的不考虑,然后等比例缩放 ,根据需求自定义
oImg.width <= oImg.height ? canva.height=720 : canva.width=1080;
oImg.width <= oImg.height ? canva.width=720*oImg.width/oImg.height : canva.height=1080*oImg.height/oImg.width;
console.log(canva.width,canva.height)
const cantext=canva.getContext('2d')
cantext.drawImage(oImg,0,0,canva.width,canva.height) //吧原图缩放后画到画布上
canva.toBlob((blob)=>{ //然后转为blob数据准备上传
let param = new FormData();
param.append('file', blob, '111.jpg');
param.set('orientation',this.imgInfo); //=增加了一个图片方向参数
uploadImgApi(param).then(res=>{ //上传
if(!res.code){ //获取返回值
this.fileId = res.data.fileId;
}else {
Toast({duration: 1500, message: res.msg})
}
}).catch(err=>{
Toast.clear()
console.log(err)
})
},'image/jpeg')
}
oImg.src=url
}
canvas实现橡皮擦,还原图片等功能
1、橡皮擦功能,先上代码,
主要用到的是canvsa中 save()、ctx.beginPath()、 ctx.arc()、ctx.clip()、ctx.clearRect()、ctx.restore()等相关方法,具体含义与作用 可以去官网查看 点这里;
//画图
let oImg=new Image(),cans=document.getElementById('canvas'); const ctx=cans.getContext('2d');
oImg.crossOrigin='';
oImg.onload=function(){
cans.width=oImg.width;
cans.height=oImg.height;
ctx.drawImage(oImg,0,0);
};
oImg.src="http://deeplor.oss-cn-hangzhou.aliyuncs.com/matting_original/2019/11/15/824e91700851429eb71c8a6a474dd065.png";
cans.onmousedown=function(e){//按下事件
document.onmousemove=(e)=>{//移动事件
const ev=e || window.event,r=10;//r是擦除范围的半径
let x=ev.clientX-cans.offsetLeft;
let y=ev.clientY-cans.offsetTop;
ctx.save();
ctx.beginPath();
ctx.arc( x, y,r, 0, Math.PI * 2, false );
ctx.clip();
ctx.clearRect( 0, 0, cans.width, cans.height );
ctx.restore();
}
document.onmouseup=(e)=>{//鼠标弹起事件
document.onmousemove=null;
document.onmouseup=null;
}}
2、实现图片还原功能(画笔功能类似,只不过不画图换成画线)
就是在画布上按照鼠标的轨迹一点点吧图片画上画布上面去。先上代码,这里需要注意的是在画图之前一定要确保图片已经onload了
let oImg=new Image(),cans=document.getElementById('canvas');
const ctx=cans.getContext('2d');
oImg.crossOrigin='';
oImg.onload=function(){
cans.width=oImg.width;
cans.height=oImg.height;
cans.onmousedown=function(e){
document.onmousemove=(e)=>{
const ev=e || window.event,r=10;//r是还原范围的半径
let x=ev.clientX-cans.offsetLeft;
let y=ev.clientY-cans.offsetTop;
ctx.save();
ctx.beginPath();
ctx.arc( x, y, r, 0, Math.PI * 2, false );
ctx.clip();
ctx.drawImage( oImg, 0, 0, cans.width, cans.height )
ctx.restore();
}
document.onmouseup=(e)=>{
document.onmousemove=null;
document.onmouseup=null;
}}
};
oImg.src="http://deeplor.oss-cn-hangzhou.aliyuncs.com/matting_original/2019/11/15/824e91700851429eb71c8a6a474dd065.png";
canvas导出图片并下载兼容性问题
一般下载图片是利用canvas的toDataURL()方法导出base64地址在利用a标签download属性下载的,单数在ie上有兼容性问题,解决方法、此方法可以解决高版本id游览器,低版本的有问题可以去参考官网的 ,这里不再赘述 点这里
总结
其实canvas还有很多问题,不过大多数都是能查到的,这些问题呢,都是不太能查到的,我是结合查询了总结出的一些问题,对于我而言是学习到了,接下来会研究下canvas一些特效,canvas是可以实现很多我们意想不到的效果的,期待以后的学习
猜你喜欢
- 2024-09-10 Python奇淫技巧之自动登录哔哩哔哩(解决滑块验证)
- 2024-09-10 html转image 保存到zip(html保存成图片)
- 2024-09-10 前端上传图片被旋转的处理方案(nba常规赛录像高清回放)
- 2024-09-10 Day 3 学习Canvas这一篇文章就够了
- 2024-09-10 JavaScript实现浏览器本地的图像移动、大小调整和裁剪
- 2024-09-10 微信内置浏览器动态生成二维码并长按识别
- 2024-09-10 Python奇淫技巧之自动登录哔哩哔哩
- 2024-09-10 JSPDF + html2canvas A4分页截断(html做分页)
- 2024-09-10 vue手把手教学~搭建web聊天室(vue简单聊天室)
- 2024-09-10 前端:从零实现一款可视化图片编辑器
- 1509℃桌面软件开发新体验!用 Blazor Hybrid 打造简洁高效的视频处理工具
- 526℃Dify工具使用全场景:dify-sandbox沙盒的原理(源码篇·第2期)
- 492℃MySQL service启动脚本浅析(r12笔记第59天)
- 472℃服务器异常重启,导致mysql启动失败,问题解决过程记录
- 469℃启用MySQL查询缓存(mysql8.0查询缓存)
- 449℃「赵强老师」MySQL的闪回(赵强iso是哪个大学毕业的)
- 429℃mysql服务怎么启动和关闭?(mysql服务怎么启动和关闭)
- 426℃MySQL server PID file could not be found!失败
- 最近发表
- 标签列表
-
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- pythoncase语句 (81)
- es6includes (73)
- windowsscripthost (67)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- chromepost (65)
- c++int转char (75)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- js判断是否是json字符串 (67)
- checkout-b (67)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- & (66)
- java (73)
- js数组插入 (83)
- linux删除一个文件夹 (65)
- mac安装java (72)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)