首先图片为什么 会变形
图片变形是因为 ctx.drawImage() 绘画图片的时候 给死了宽和高,所以不同尺寸的图片会因为 自己写死的宽高 而拉伸或者压缩,因此图片才会变形。
我的解决方案
重要属性 ctx.clip() 从原始画布中剪切任意形状和尺寸
之前画用户圆形头像用到了clip裁剪。
了解到 clip 可以裁剪,尝试 把我当前的 图片等比例的放大或者缩小 直到撑满我的裁剪区域,那样我的图片不就不会变形了。
什么? 你问我怎么等比例放大缩小?
小学数学知识 ~ _ ~ 图片宽 / 图片高 = x / y
上代码
- ctx: 画布的上下文环境
- img: 需要绘制的图片
- imageAttributes: 图片的属性 用来获取图片的宽和高 (这里要说一下 开始我是在 下面方法中去获取图片的宽高但是返回的数据慢 所以只能一开始就拿到 要渲染图片的属性,然后再开始 初始化canvas去渲染)
- x: 绘制图片的x坐标
- y:绘制图片的y坐标
- boxWidth:裁剪区域的宽
- boxHeight:裁剪区域的高
// 图片变形解决方案 img:绘画的图片 imageAttributes:得到图片属性 看情况可能是个数组,可以是对象 x y:图片的坐标 boxWidth:裁剪区域的宽 boxHeight:裁剪区域的高 preventPictureDistortion(ctx,img,imageAttributes, x, y, boxWidth,boxHeight){ let {width,height} = imageAttributes console.log(width,height,'图片的实际宽高') let imgScale = width / height // 图片的宽高比 console.log(imgScale,'计算的图片宽高比') let imgW,imgH // 计算后得到图片的宽高 let offsetW,offsetH // 绘图时需要偏移的坐标 是用来 让图片居中的 就是截取中间部分 不是从 0 0 开始截取 imgH = boxHeight;imgW = imgScale * imgH;offsetW = (imgW-boxWidth) / 2;offsetH=0 // 开始计算图片宽高 以及偏移坐标 if(imgW < boxWidth){imgW = boxWidth;imgH = imgW / imgScale; offsetH = (imgH-boxHeight) / 2; offsetW = 0} // 开始绘制 容纳图片的裁剪区域 ctx.save() ctx.beginPath() this.roundedRectangle(ctx, x, y, boxWidth, boxHeight, uni.upx2px(12),'#fff') // 这个方法是用来绘制圆角矩形的 百度来的 ctx.clip() ctx.drawImage(img, x-offsetW, y-offsetH,imgW, imgH) ctx.restore() }
绘制圆角矩形的方法
- ctx: 画布的上下文环境
- x: 绘制圆角矩形的x坐标
- y:绘制圆角矩形的y坐标
- width: 绘制矩形的宽
- height:绘制矩形的高
- r:绘制矩形的 圆角
- color:矩形的 背景颜色
// 画圆角矩形方法 roundedRectangle(ctx, x, y, width, height, r,color){ ctx.beginPath(); ctx.moveTo(x + r, y); ctx.fillStyle = color;//矩形填充颜色 ctx.lineTo(x + width - r, y); ctx.arc(x + width - r, y + r, r, Math.PI*1.5, Math.PI*2); ctx.lineTo(x + width, y + height - r); ctx.arc(x + width - r, y + height - r, r, 0, Math.PI*0.5); ctx.lineTo(x + r, y + height); ctx.arc(x + r, y + height - r, r, Math.PI*0.5, Math.PI); ctx.lineTo(x, y + r); ctx.arc(x + r, y + r, r, Math.PI, Math.PI*1.5); ctx.fill(); }