uni-app canvas 画海报图片变形解决方案

时间:2024-03-09 14:41:00

首先图片为什么 会变形


图片变形是因为 ctx.drawImage() 绘画图片的时候 给死了宽和高,所以不同尺寸的图片会因为 自己写死的宽高 而拉伸或者压缩,因此图片才会变形。

我的解决方案

重要属性 ctx.clip()  从原始画布中剪切任意形状和尺寸  

之前画用户圆形头像用到了clip裁剪。

了解到 clip 可以裁剪,尝试 把我当前的 图片等比例的放大或者缩小  直到撑满我的裁剪区域,那样我的图片不就不会变形了。

什么? 你问我怎么等比例放大缩小? 

小学数学知识 ~ _ ~ 图片宽 / 图片高 = x / y

上代码

  1. ctx: 画布的上下文环境
  2. img: 需要绘制的图片
  3. imageAttributes: 图片的属性 用来获取图片的宽和高      (这里要说一下 开始我是在 下面方法中去获取图片的宽高但是返回的数据慢 所以只能一开始就拿到 要渲染图片的属性,然后再开始 初始化canvas去渲染)
  4. x: 绘制图片的x坐标
  5. y:绘制图片的y坐标
  6. boxWidth:裁剪区域的宽
  7. 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()
                            }

绘制圆角矩形的方法

  1. ctx: 画布的上下文环境
  2. x: 绘制圆角矩形的x坐标
  3. y:绘制圆角矩形的y坐标
  4. width: 绘制矩形的宽
  5. height:绘制矩形的高
  6. r:绘制矩形的 圆角
  7. 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();
                            }