• 微信小程序 canvas 实现图片拉伸、压缩与裁剪


    注意:本文转载自https://blog.csdn.net/vivian_jay/article/details/68933161

     

    一、canvas绘图API

    工欲善其事;必先利其器。 
    隆重请出主角:canvas绘图函数drawImage(),酱酱酱~

    它能做什么: 
    1. 绘制图像:将加载的图像绘制到canvas上; 
    2. 绘制画布:将画好的一个canvas画到另一个canvas上; 
    3. 绘制视频:差不多就是用来视频截图,哇(@ο@) 好厉害。

    怎么做(敲黑板:今天只教绘制图像啊,老师没备课): 
    1. 获取图片

    //1. 可以直接获取DOM元素
    var img = document.getElementById("imgId")
    //2. 或者新建一个
    var img = new Image()
    img.src = "imgsrc.jpg"
    • 1
    • 2
    • 3
    • 4
    • 5
    1. 获取canvas上下文
    //1. 获取画布
    var canvas = document.getElementById("canvasId")
    //2. 获取画布上下文
    var ctx = canvas.getContext("2d")
    • 1
    • 2
    • 3
    • 4
    1. 在上下文画画!
    img.onload = function(){
        ctx.drawImage(img,sx,sy,swidth,sheight,x,y,width,height)
    }
    • 1
    • 2
    • 3

    参数释义: 
    drawImage有三种添加参数的情况,如下:

    1. 只规定原始图片开始剪切的位置,默认填充剩余宽高到画布上:
    drawImage(img,sx,sy)
    • 1
    1. 从指定位置裁剪原始图片指定宽高,填充到画布上:
    drawImage(img,sx,sy,swidth,sheight)
    • 1
    1. 从指定位置裁剪原始图片指定宽高,从指定位置开始显示到画布上指定宽高:
    drawImage(img,sx,sy,swidth,sheight,x,y,width,height)
    • 1

    这里盗个图解释一下: 
    drawImage参数值

    二、拉伸并图片

    原始图片的宽高较之显示区域较小,就需要美美地拉伸一下。

    1. 原始图片宽高均小于显示区域 
    默认情况下会将原始图片的宽高都扯开成刚好铺满画布。这个就不管了,让它自由填充吧,freedom~

    2. 原始图片仅宽度小于显示区域:黄色img,蓝色canvas

    原始图片仅宽度小于显示区域

    默认情况会将图片宽度拉伸,高度压缩,图片会被压得很~扁~ 
    思路:将原始图片宽度拉开成现实区域宽度,而将高度等比例拉开,并且将超出部分上下各剪裁一半。

    拉伸2

    函数参数设置如下:

    ctx.drawImage(img, 0, (h - 200/dw)/2, w, 200/dw, 0, 0, 300, 200)
    • 1

    3.原始图片仅高度小于显示区域:

    原始图片仅高度小于显示区域

    默认情况会将图片高度拉伸,宽度压缩,图片内容会被挤得很~细~ 
    思路:将原始图片高度拉开成现实区域宽度,而将宽度等比例拉开,并且将超出部分左右各剪裁一半。

    拉伸3

    参数设置如下:

    ctx.drawImage(img, (w - 300/dh)/2, 0, 300/dh, h, 0, 0, 300, 200)
    • 1

    三、压缩并裁剪图片

    原始图片的宽高较之显示区域较大,就需要小小地压缩一下。

    基本思路:在原始图片的宽高均大于显示区域时,首先需要确定我们以宽/高中的哪一个为基准进行压缩,因此需要计算原始图片的宽/高与显示区域的宽/高的比例,以比例高(也就是相差小)的那个作为基准,等比例压缩后相差多的那个需要裁减掉一部分。

    1. dw < dh

    dh>dw

    默认情况会将图片高度、宽度分别按各自的比例压缩,图片内容会被拉得很~扁~ 
    思路:将原始图片宽度压缩成现实区域宽度,而将高度等比例拉开,并且将超出部分上下各剪裁一半。【同拉伸情况2】

    拉伸2

    函数参数设置如下:

    ctx.drawImage(img, 0, (h - 200/dw)/2, w, 200/dw, 0, 0, 300, 200)
    • 1

    2. dh < dw

    dh < dw

    默认情况会将图片高度、宽度按各自比例压缩,图片内容会被挤得很~细~ 
    思路:将原始图片高度拉开成现实区域宽度,而将宽度等比例拉开,并且将超出部分左右各剪裁一半。【同拉伸情况3】

    拉伸3

    参数设置如下:

    ctx.drawImage(img, (w - 300/dh)/2, 0, 300/dh, h, 0, 0, 300, 200)
    • 1

    四、小结

    其实不管是先拉伸再裁剪还是先压缩再裁剪,基本思想都是一样的:把图片从默认的填充比例中拯救出来,让它能等比例地变换大小,避免被奇怪的缩放比例搞得颜值比较奇怪。本文中的默认情况均是指直接使用img标签上传图片的情况,相当于:

    ctx.drawImage(img,0,0,w,h,0, 0, 300, 200)
    • 1

    划重点!上文中的代码综合如下:

    var canvas = $(".good-img")[0]
    var ctx = canvas.getContext("2d")
    var img = new Image()
    img.src = "images/3.jpg"
    img.onload = function () {
        var w = img.width
        var h = img.height
        var dw = 300/w          //canvas与图片的宽高比
        var dh = 200/h
        var ratio       
        // 裁剪图片中间部分
        if(w > 300 && h > 200 || w < 300 && h < 200){
            if (dw > dh) {
                ctx.drawImage(img, 0, (h - 200/dw)/2, w, 200/dw, 0, 0, 300, 200)
            } else {
                ctx.drawImage(img, (w - 300/dh)/2, 0, 300/dh, h, 0, 0, 300, 200)
            }
        }
        // 拉伸图片
        else{
            if(w < 300){
                ctx.drawImage(img, 0, (h - 200/dw)/2, w, 200/dw, 0, 0, 300, 200)
            }else {
                ctx.drawImage(img, (w - 300/dh)/2, 0, 300/dh, h, 0, 0, 300, 200)
            }
        }
    }
  • 相关阅读:
    Python的time模块随笔。
    生成器递归解决八皇后问题(勉强理解)
    Python历史「解密」Python底层逻辑 及Python 字节码介绍(转帖)
    可迭代(Interable),迭代器(Iterator),生成器(generator)的手记(11月26日再次修改)
    __getattr__,__setattr__,__delattr__,__getattribute__,记录
    关于property的一些记录,以及描述符(descriptor)中__get__,__set__,__delete__的属性使用。
    Python魔法方法之容器部方法(__len__,__getitem__,__setitem__,__delitem__,__missing__)(更新版本)
    Mac下PyCharm快捷键大全!(每天记住几个)
    开笔了,就写一下,hasattr,getattr,setattr。
    GUI
  • 原文地址:https://www.cnblogs.com/boboweiqi/p/9523793.html
Copyright © 2020-2023  润新知