zoukankan      html  css  js  c++  java
  • canvas drawImage绘图实现contain和cover的效果

    我们常用到css的background-size属性中的contain和cover属性,来实现背景图的适配,

    本文将要介绍在用canvas绘制图片的时候,如何实现contain或cover效果呢?

    contain概念

    缩放背景图片以完全装入背景区,可能背景区部分空白。contain 尽可能的缩放背景并保持

    图像的宽高比例(图像不会被压缩)。该背景图会填充所在的容器。当背景图和容器的大小

    不同时,容器的空白区域(上/下或者左/右)会显示由 background-color 设置的背景颜色。

    说白了就是保持图片宽高比并保证图片的长边能完整显示,用到canvas的 drawImage(img, dx, dy, dw, dh)方法

    参数dx, dy分别表示图片左上角顶点的横 纵坐标

    参数dw, dh分别表示定义图片的宽 高。

    公式推导

    需要分两种情况,

    ①当图片宽高比 <= 画布宽高比时,如图:

    已知:  
     imgRatio = imgWidth / imgHeight  canvasRatio = canvasWidth / canvasHeight 由图得出条件:  imgHeight = canvasHeight 推导:  imgWidth = imgRatio * imgHeight = imgRatio * canvasHeight
    即:
     dw = imgRatio * canvasHeight
     dh = canvasHeight
     dx = (canvasWidth - imgWidth) / 2  dy = 0

    ②当图片的宽高比 >= canvas画布宽高比时, 如图:

    同理推导出:
     imgWidth = canvasWidth
     imgHeight = imgWidth / imgRatio = canvasWidth / imgRatio

    即: 
    dw = canvasWidth
     dh = dw / imgRatio
     dx = 0
     dy = (canvasHeight - dh) / 2

    所以以contain方式适应画布的代码为:

    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    var img = new Image();
    img.src = "images/pic1.jpg";
    let dx, dy, dw, dh, imgRatio, canvasRatio;
    canvasRatio = canvas.width / canvas.height;
    
    // contain 方式
    img.onload = function () {
      imgRatio = img.width / img.height;
      if(imgRatio <= canvasRatio){
        dw = imgRatio * canvas.width
        dh = canvas.height
        dx = (canvas.width - dw) / 2
        dy = 0
      }else{
         dw = canvas.width
        dh = dw / imgRatio
        dx = 0
        dy = (canvas.height - dh) / 2 
      }
      ctx.drawImage(img, dx, dy, dw, dh)
    }

    cover概念

    缩放背景图片以完全覆盖背景区,可能背景图片部分看不见。和 contain 值相反,

    cover 值尽可能大的缩放背景图像并保持图像的宽高比例(图像不会被压扁)。

    该背景图以它的全部宽或者高覆盖所在容器。当容器和背景图大小不同时,

    背景图的 左/右 或者 上/下 部分会被裁剪。

     说白了就是保持图片宽高比的同时保证图片的短边能完全显示出来,

    因为可能会有裁剪,所以用到canvas的drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh)方法。

    参数sx, sy分别表示源图片被截取部分左上角顶点的横 纵坐标

    参数sw, sh 分别表示源图片被截取部分的宽 高

    参数 dx, dy, dw, dh 分别表示切片后将要在画布上绘制的左上角顶点坐标及绘制的宽高。

    公式推导

    同样分两种情况,

    ① 图片宽高比 <= 画布宽高比时, 如图:

    已知: 
     imgRatio = imgWidth / imgHeight
     canvasRatio = canvasWidth / canvasHeight
    由图知:
     dw = canvasWidth
     dh = canvasHeight
     dx = 0
     dy = 0
    此时图片的宽要在画布完整展示,所以源图片要裁剪的区域为:

     sw = imgWidth
     sh = sw / canvasRatio
     sx = 0
     sy = (imgHeight - sh) / 2

    ②当图片宽高比 >= 画布宽高比时, 如图:

    同理:
     此时图片的高要在画布完整展示,源图片的裁剪区域为:
     sh = imgHeight
     sw = sh * canvasRatio

     sx = (imgWidth - sw) / 2
     sy = 0

    所以以cover方式适应画布的代码为:

    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    var img = new Image();
    img.src = "images/pic1.jpg";
    let sx, sy, sw, sh, imgRatio, canvasRatio;
    canvasRatio = canvas.width / canvas.height;
    // cover 方式
    img.onload = function () {
      imgRatio = img.width / img.height;
      if(imgRatio <= canvasRatio){
        sw = img.width
        sh = sw / canvasRatio
        sx = 0
        sy = (img.height - sh) / 2
      }else{
        sh = img.height
        sw = sh * canvasRatio
        sx = (img.width - sw) / 2
        sy = 0
      }   
      ctx.drawImage(img, sx, sy, sw, sh, 0, 0, canvas.width, canvas.height) // 因为是cover覆盖, 所以dx,dy都是0,绘制宽高即为canvas宽高 
    }
  • 相关阅读:
    python join的用法
    python json中的 dumps loads函数
    ubuntu 初始配置
    如何为ubuntu配置java环境
    Ubuntu系统如何安装软件
    取模与取余
    基本数据类型
    js面试题——作用域和闭包
    js面试题-原型和原型链
    js面试题-变量类型和计算
  • 原文地址:https://www.cnblogs.com/AIonTheRoad/p/14063041.html
Copyright © 2011-2022 走看看