zoukankan      html  css  js  c++  java
  • Canvas图片处理

    前言

    图片处理 在前端业务中并不陌生。例如手机自带相机拍出的照片通常好几兆,但如果只是用作头像就显然太大,需要 图片压缩 后再上传服务器;再例如前段时间比较火的迎国庆换头像,就用到了 图片与图片的合成。本文将介绍前端常见的 Canvas 图片处理方法。

    日常用到的图片处理方式都有哪些

    前端日常业务的图片处理大概分为以下几种:

    • 图片缩放
    • 图片剪裁
    • 图片与图片的合成
    • 图片插入画笔(手写签名)
    • 图片插入文字

    图片缩放图片剪裁图片与图片的合成 主要用了 drawImage 方法;
    图片插入画笔 主要用了 Canvas-路径;
    图片插入文字 主要用了 fillText 方法。

    图片处理相关的 Canvas 技术

    CanvasRenderingContext2D.drawImage()

    在画布上绘制图像、画布或视频。

    void ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
    
    参数 描述
    image 规定要使用的图像、画布或视频。
    sx 可选。开始剪切的 x 坐标位置。
    sy 可选。开始剪切的 y 坐标位置。
    sWidth 可选。被剪切图像的宽度
    sHeight 可选。被剪切图像的高度。
    dx 在画布上放置图像的 x 坐标位置。
    dy 在画布上放置图像的 y 坐标位置。
    dWidth 可选。要使用的图像的宽度。(伸展或缩小图像)
    dHeight 可选。要使用的图像的高度。(伸展或缩小图像)

    CanvasRenderingContext2D.fillText()

    fillText() 方法在画布上绘制填色的文本。文本的默认颜色是黑色。

    void ctx.fillText(text, x, y [, maxWidth]);
    
    参数 描述
    text 规定在画布上输出的文本。
    x 开始绘制文本的 x 坐标位置(相对于画布)。
    y 开始绘制文本的 y 坐标位置(相对于画布)。
    maxWidth 可选。允许的最大文本宽度,以像素计。

    技术点讲解

    图片缩放

    void ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
    

    sx, sy, dx, dy 设置为 0;
    sWidth, sHeight 设置为图片宽长;
    dWidth, dHeight 设置为画布宽长;
    等比例图片缩放:根据 image 的长宽,等比例调成画布的长宽;
    不等比图片例缩放:任意的调整画布的长宽;

    图片剪裁

    void ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
    

    sx, sy, sWidth, sHeight 取其中一部分填充到画布上。

    图片与图片的合成

    使用多次drawImage会把多张图片绘制到一张画布。

    注意: 因为本地图片和用户图片和成会有跨域问题 所以需要添加属性 crossOrigin 为 anonymous

    图片插入画笔(手写签名)

    利用鼠标事件操纵 Canvas 画出路线。

    1. ctx.beginPath(); // 开始
    2. ctx.moveTo(e.offsetX, e.offsetY); // 设置起点
    3. ctx.lineTo(e.offsetX, e.offsetY); // 移动到当前点
    4. ctx.stroke(); // 绘制
    5. ctx.closePath(); // 结束

    事件流程:

    • mousedown 执行 1 2;
    • mousemove 执行 3 4;
    • mouseout 或 mouseup 时移除 mousemove,执行 5。

    图片插入文字

    void ctx.fillText(text, x, y [, maxWidth]);
    
    var canvas = document.createElement('canvas');
    canvas.width = uploadImg.width;
    canvas.height = uploadImg.height;
    var ctx = canvas.getContext('2d');
    ctx.drawImage(uploadImg, 0, 0, canvas.width, canvas.height);  // 图片画进画布
    ctx.fillStyle = "#f00"; // 设置字体颜色
    ctx.font = "14px Arial";  // 设置字体大小,字体样式
    ctx.fillText("我是一段文字", 10, 10);  // 插入
    

    实战栗子

    迎国庆换头像

    是将用户上传的图片和本地头像框子图片合成,用到了图片缩放,图片剪裁,图片和图片的合成。

    在线演示Github地址

    实现思路是

    1. 新建画布;
    2. new Image() 把头像框图片处理到缓存;
    3. 用户上传头像,用 FileReader 读出图片资源,然后用 new Image() 放至缓存;
    4. 计算用户上传头像的中间区域, 计算坐标和长宽(取正方形);
    5. 将 用户头像 Image 用 drawImage 绘制到画布(用算好的坐标取中间区域正方形);
    6. 将 头像框 Image 用 drawImage 绘制到画布;
    7. 把画布导出为图片。

    头像框图片:

    var imgFrame = new Image();  // 头像框图
    imgFrame.setAttribute("crossOrigin", 'anonymous');
    imgFrame.src = imgTopPathList[imgTopPathIndex];
    

    用户上传图片:

    // 用户上传图
    var img = new Image();
    // 读文件
    var reader = new FileReader();
    reader.onload = function (event) {
        img.src = event.target.result;
    }
    // input onchange
    input.onchange = function (event) {
        reader.readAsDataURL(event.target.files[0]);
    }
    

    计算中间区域坐标(取最大中间区域):

    var iw = img.width;   // 用户上传图片宽
    var ih = img.height;  // 用户上传图片高
    if (!iw || !ih) return;
    var r = w / h;        // 目标图片宽高比
    
    // 计算裁剪
    var sx, sy, sWidth, sHeight;
    if (iw / ih > r) {
    sHeight = ih;
    sWidth = sHeight * r;
    } else {
    sWidth = iw;
    sHeight = sWidth / r;
    }
    sx = (iw - sWidth) / 2;
    sy = (ih - sHeight) / 2;
    

    合成:

    const [w, h, s] = [150, 150, 3];  // 生成图片宽,  生成图片高,  生成图片放大倍数
    
    var canvas = document.createElement('canvas');
    canvas.width = w * s;
    canvas.height = h * s;
    var ctx = canvas.getContext('2d');
    ctx.fillStyle = '#ffffff';  // canvas 背景颜色
    ctx.drawImage(img, sx, sy, sWidth, sHeight, 0, 0, w * s, h * s);  // canvas添加用户图
    ctx.drawImage(imgTop, 0, 0, w * s, h * s);  // canvas添加头像框图
    
    var src = canvas.toDataURL("image/png");
    // src 拿到的就是合成图片的url
    

    图片添加文字

    上传图片,输入文字,可调整文字大小、样式、颜色、坐标。

    在线演示; Github地址

    图片编辑

    模仿微信截图,上传图片后,可在图片上插入矩形(开发中)、插入画笔、插入文字。

    在线演示; Github地址

    whosmeya.

  • 相关阅读:
    Sublime Text 包管理工具及扩展大全
    MVC5路由系统机制详细讲解
    Asp.net MVC中Html.Partial, RenderPartial, Action,RenderAction 区别和用法【转发】
    解决Html.CheckBoxFor中”无法将类型 bool 隐式转换为 bool。存在一个显式转换..."的方法
    [C#]List的Sort()、Find()、FindAll()、Exist()的使用方法举例
    jqGrid配置属性说明
    MSSQL查找前一天,前一月,前一年的数据,对比当前时间记录查找超过一年,一月,一天的数据
    【转】linux expr命令参数及用法详解
    ls -alrth 及ls 详解
    修改linux文件权限命令:chmod
  • 原文地址:https://www.cnblogs.com/whosmeya/p/12557598.html
Copyright © 2011-2022 走看看