前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【JS】928- 用 Canvas 编辑你的图片

【JS】928- 用 Canvas 编辑你的图片

作者头像
pingan8787
发布2021-04-26 11:25:04
4.5K0
发布2021-04-26 11:25:04
举报
文章被收录于专栏:前端自习课前端自习课

写在前面

最近接到一个需求:线下质检时根据上传的图片和实物进行对比检测,需要在图片上的动态标记出有瑕疵或污点等位置,便于后续流程检测和记录。 想到了之前用过的 canvas 可以实现这个功能,话不多说,让我们一起认识一下 canvas

canvas 自我介绍

大家好,我是 canvas ,我能让大家通过 canvas 标签,用JavaScript来绘制图形。除此之外,动画,游戏图形,数据可视化,照片处理和实时视频处理都难不倒我噢~

一、我的兼容性(心有多大,舞台就有多大)

大家使用前端技术前可以在Can I Use上查询一下兼容性噢~ 我就在里面找到了自己呢:

canvas兼容性

二、我能做什么**(能力越大,责任越大)

我来告诉大家我是怎么工作的,从简单的开始噢(hello world~)

1、拿起纸和笔

代码语言:javascript
复制
// .html
<canvas id="tutorial" width="150" height="150"></canvas>

// .js
const canvas = document.getElementById('tutorial');
// ctx就是我的纸了
const ctx = canvas.getContext('2d');
// 准备一下我的笔(就拿个红色吧~)
ctx.strokeStyle = 'red';
// 填充颜色
ctx.fillStyle = 'red';

2、基本用法

我自己总结了一些方法,大家用起来就快多了

  • 画线

line

代码语言:javascript
复制
ctx.beginPath();
ctx.lineWidth="5";
ctx.strokeStyle="red"; // 红色路径
ctx.moveTo(0,75);
ctx.lineTo(250,75);
ctx.stroke(); // 进行绘制

ctx.beginPath();
ctx.strokeStyle="blue"; // 蓝色路径
ctx.moveTo(50,0);
ctx.lineTo(150,130);
ctx.stroke(); // 进行绘制
  • 画个圈圈

arc

代码语言:javascript
复制
ctx.beginPath();
// ctx.arc(x,y,r,sAngle,eAngle,counterclockwise);
// x: 圆的中心的 x 坐标。
// y: 圆的中心的 y 坐标。
// r: 圆的半径。
// sAngle: 起始角,以弧度计。(弧的圆形的三点钟位置是 0 度)。
// eAngle: 结束角,以弧度计。
// counterclockwise: 可选。规定应该逆时针还是顺时针绘图。False = 顺时针,true = 逆时针。
ctx.arc(100,75,50,0,2*Math.PI);
ctx.stroke();
  • 画个框框

arc

代码语言:javascript
复制
// x: 矩形左上角的 x 坐标
// y: 矩形左上角的 y 坐标
// width: 矩形的宽度,以像素计
// height: 矩形的高度,以像素计
// 填充矩形
ctx.fillRect(x: 20, y: 20, width: 150, height: 100);
// 无填充矩形
ctx.strokeRect(20,20,150,100);

好啦,以上是我的基本技能,有兴趣的话可以在MDN WEB上查看我的全部技能噢~

回归到需求上,我们开发者应该如何使用 canvas 完成需求功能呢?

实践

结合 canvas 技能,方案设计思路如下:

  • 获取适配的图片
  • 转换图片:按照图片 1:1 绘制画布
  • 动态编辑:在画布上标记操作,可进行增删改
  • 生成图片:画布转换为图片
1、获取并转换图片 drawImage
代码语言:javascript
复制
<img
  style={{ width: 100px, height: 100px }}
  src="https://test.jpg"
  onLoad={onLoad}
/>
<canvas></canvas>

function onLoad() {
  // 设置canvas为图片大小
  canvas.height = img.height;
  canvas.width = img.width;
  // 绘制图片 (0,0)开始1:1绘制img
  // ctx.drawImage(img,x,y,width,height);
  ctx.drawImage(img, 0, 0, img.width, img.height);
}
2、编辑功能 (此处主要实现框选功能)
代码语言:javascript
复制
canvas.addEventListener("mousedown", onMouseDown);
canvas.addEventListener("mousemove", onMouseMove);

function getPointOnCanvas() {
  // canvas相对于视窗的位置集合
  const rect = canvas.getBoundingClientRect();
  return {
    x: x - rect.left * (canvas.width / rect.width),
    y: y - rect.top * (canvas.height / rect.height)
  }
}

function onMouseDown(event) {
  var x = event.pageX;
  var y = event.pageY;
  // 获取起点
  startPoint = getPointOnCanvas(canvas, x, y);

  ctx.beginPath();
  ctx.moveTo(startPoint.x, startPoint.y);
}

function getRectParam(curPoint) => {
  const _w = curPoint.x - startPoint.x;
  const _h = curPoint.y - startPoint.y;
  const _startPoint = _w < 0 || _h < 0 ? curPoint : startPoint;
  return {
    _startPoint,
    _w,
    _h
  };
};

function drawRect() {
  // 获取绘制矩形需要的参数
  const newRect = getRectParam(curPoint)
  // 绘制矩形
  ctx.beginPath();
  ctx.rect(
    newRect._startPoint.x,
    newRect._startPoint.y,
    Math.abs(newRect._w),
    Math.abs(newRect._h)
  );
  ctx.stroke();
}

function mousemove(event) {
  const x = event.pageX;
  const y = event.pageY;
  // 获取
  const curPoint = getPointOnCanvas(canvas, x, y);
  drawRect();
};
3、canvas 转图片
代码语言:javascript
复制
const dataURL = canvas.toDataURL('image/png')

以上是部分代码,来看看编辑效果:

目前需求已顺利上线,质检师的使用反馈很不错。

写在后面

希望通过本文给大家带来一种前端处理图片的思路,有兴趣的同学可以尝试一下 canvas 的其他功能,如:添加文字,编辑的撤回等等。

接下来,会陆续推出三无项目重构的踩坑之旅、跨应用的拖拽能力实践等。每天进步一点点,质变从关注 大转转 FE 开始!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-04-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端自习课 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 写在前面
    • canvas 自我介绍
      • 一、我的兼容性(心有多大,舞台就有多大)
      • 二、我能做什么**(能力越大,责任越大)
    • 实践
      • 1、获取并转换图片 drawImage
      • 2、编辑功能 (此处主要实现框选功能)
      • 3、canvas 转图片
    • 写在后面
    相关产品与服务
    媒体处理
    媒体处理(Media Processing Service,MPS)是一种云端音视频处理服务。基于腾讯多年音视频领域的深耕,为您提供极致的编码能力,大幅节约存储及带宽成本、实现全平台播放,同时提供视频截图、音视频增强、内容理解、内容审核等能力,满足您在各种场景下对视频的处理需求。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档