面试中canvas绘制图片模糊图片问题处理


Posted in Javascript onMarch 13, 2022

问题:canvas绘制图片,图片变模糊

设定一个一定尺寸的canvas,我这里设置的画布大小是400px*400px。当一张图片完全画到画布上的时候,大概率都会出现图片模糊的情况。
我拿下面一张图片画到canvas上作为例子,看上去应该比较明显的有模糊的感觉。

面试中canvas绘制图片模糊图片问题处理

单方面的去修改图片精度,换成更高清的图片,事实证明确实有一丢丢用,但是效果不是很明显。况且我当时那个图片由于是手绘的,大小有5M,也不会切片加载图片,直接整个加载非常耗时。

那么如何去处理这样的问题呢?

生活中应该大家都遇到过这样的情况,同样的1080p的视频,在大屏显示器上看和手机上看效果是不一样的,大屏往往会让人感觉一种模糊感。而在手机小屏幕上,就会感觉异常的清晰。

要点:两个点

通过上面的一个例子,我们可以将图片放大,然后再绘制进原先大小的canvas中,这样图片的精度受损会比较小

了解canvas的绘制原理(*打星号)

canvas其实就是一张画布,所以如果可以的话,你可以将它放大,可以发现它也是有一个个的像素组成的。

面试中canvas绘制图片模糊图片问题处理

如上图,可以看到一个个的网格。假设我们需要在上面绘制一条1px的线条,就会得到上面的效果。
但是canvas是的绘制方式是从中线开始绘制,并向两侧延伸的。 

面试中canvas绘制图片模糊图片问题处理

他会以图中的红线作为中线,向两边延伸,从而得到1px的纵向线条。但是像素是不允许0.5px的出现的,所以它索性就直接再延伸一点,将像素给填满。所以你看到的效果是下面这种?

面试中canvas绘制图片模糊图片问题处理

所以当一张图片被绘制到canvas中的时候,很多区域都会被绘制两次,所以出现重叠导致你看到的图片是模糊的。
其实马赛克的原理也是,相邻像素点之间的颜色进行运算进行交叉覆盖,起到打码的效果。
所以有几种不同的解决方案。

解决方案

方法一

在绘制的时候,如果是线条,可以通过移动0.5px找准中线来达到目的,例如:

ctx.moveTo(100.5,100.5);
ctx.lineTo(200.5,100.5);

方法二

如果是图片,可以通过放大一倍canvas大小,但是通过css保持canvas大小不变,然后再绘制进canvas中,这样在canvas放大一倍的情况下绘制进去图片,然后通过css缩小canvas到原来大小达到目的。

示例

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>canvas绘制图片模糊</title>
  </head>
  <body>
    <img
      id="img"
      src="https://desk-fd.zol-img.com.cn/t_s960x600c5/g2/M00/09/0C/Cg-4WVV6jWmIczjzAAdzu1eYHzwAAFK1wD9poMAB3PT053.jpg"
      width="100px"
      height="100px"
      style="visibility: hidden;"
    />
    <canvas id="canvas" width="400px" height="400px"></canvas>
    <canvas
      id="canvas2"
      width="800px"
      height="800px"
      style="width: 400px; height: 400px;"
    ></canvas>
  </body>
  <script>
    function init() {
      console.log(1234);
      let canvas = document.getElementById("canvas");
      let img = document.getElementById("img");
      let context = canvas.getContext("2d");
      context.drawImage(img, 0, 0, 400, 400);
 
      let canvas2 = document.getElementById("canvas2");
      let context2 = canvas2.getContext("2d");
      context2.drawImage(img, 0, 0, 800, 800);
    }
    window.onload = init;
  </script>
</html>

为了方便,就都写在一个html中了,图片也是找的网图。左边是未处理,也就是代码中的canvas效果,右边是通过方法2处理后的,也就是canvas2效果,请自行鉴别嗷。

面试中canvas绘制图片模糊图片问题处理

方法三

可以通过 transform:scale(0.5)的方式对图片进行缩放,再绘制到canvas中

以上就是面试中canvas绘制图片模糊图片问题处理的详细内容,更多关于面试canvas绘制图片模糊解决的资料请关注三水点靠木其它相关文章!

 

Tags in this post...

Javascript 相关文章推荐
浅谈JavaScript中面向对象技术的模拟
Sep 25 Javascript
jquery 操作两个select实现值之间的互相传递
Mar 07 Javascript
JavaScript中的函数的两种定义方式和函数变量赋值
May 12 Javascript
javascript属性访问表达式用法分析
Apr 25 Javascript
Jquery实现顶部弹出框特效
Aug 08 Javascript
javascript实现图片延迟加载方法汇总(三种方法)
Aug 27 Javascript
开启BootStrap学习之旅
May 04 Javascript
用jquery获取自定义的标签属性的值简单实例
Sep 17 Javascript
Node.js检测端口(port)是否被占用的简单示例
Sep 29 Javascript
Bootstrap popover用法详解
Dec 22 Javascript
vue左右侧联动滚动的实现代码
Jun 06 Javascript
vue实现滑动切换效果(仅在手机模式下可用)
Jun 29 Javascript
Javascript中async与await的捕捉错误详解
Mar 03 #Javascript
Vue如何清空对象
Mar 03 #Vue.js
Vue中Object.assign清空数据报错的解决方案
Mar 03 #Vue.js
javascript之Object.assign()的痛点分析
Mar 03 #Javascript
vue实现移动端div拖动效果
Mar 03 #Vue.js
vue实现滑动解锁功能
JavaScript最完整的深浅拷贝实现方式详解
Feb 28 #Javascript
You might like
php生成随机密码的三种方法小结
2010/09/04 PHP
php设计模式 Delegation(委托模式)
2011/06/26 PHP
PHP高级编程实例:编写守护进程
2014/09/02 PHP
PHP使用array_multisort对多个数组或多维数组进行排序
2014/12/16 PHP
Yii2中设置与获取别名的函数(setAlias和getAlias)用法分析
2016/07/25 PHP
Swoole源码中如何查询Websocket的连接问题详解
2020/08/30 PHP
Gambit vs ForZe BO3 第三场 2.13
2021/03/10 DOTA
asp(javascript)全角半角转换代码 dbc2sbc
2009/08/06 Javascript
EXT窗口Window及对话框MessageBox
2011/01/27 Javascript
设为首页加入收藏兼容360/火狐/谷歌/IE等主流浏览器的代码
2013/03/26 Javascript
jquery实现可旋转可拖拽的文字效果代码
2016/01/27 Javascript
实用jquery操作表单元素的简单代码
2016/07/04 Javascript
require简单实现单页应用程序(SPA)
2016/07/12 Javascript
14 个折磨人的 JavaScript 面试题
2016/08/08 Javascript
jquery validate表单验证插件
2016/09/06 Javascript
jQuery分页插件jquery.pagination.js使用方法解析
2017/02/09 Javascript
Webpack打包css后z-index被重新计算的解决方法
2017/06/18 Javascript
Vue.js实现可配置的登录表单代码详解
2018/03/29 Javascript
Next.js项目实战踩坑指南(笔记)
2018/11/29 Javascript
基于javascript实现碰撞检测
2020/03/12 Javascript
vue基于Echarts的拖拽数据可视化功能实现
2020/12/04 Vue.js
[20:57]Ti4主赛事第三天开幕式
2014/07/21 DOTA
Python爬取读者并制作成PDF
2015/03/10 Python
使用Protocol Buffers的C语言拓展提速Python程序的示例
2015/04/16 Python
python生成圆形图片的方法
2020/03/25 Python
python3下使用cv2.imwrite存储带有中文路径图片的方法
2018/05/10 Python
python如何发布自已pip项目的方法步骤
2018/10/09 Python
Python获取网段内ping通IP的方法
2019/01/31 Python
python 用opencv实现图像修复和图像金字塔
2020/11/27 Python
浅谈CSS3鼠标移入图片动态提示效果(transform)
2017/11/06 HTML / CSS
H5混合开发app如何升级的方法
2018/01/10 HTML / CSS
2014年大学生党课心得体会范文
2014/03/29 职场文书
动漫设计与制作专业推荐信
2014/07/07 职场文书
工程安全生产协议书
2014/11/21 职场文书
2015年汽车销售经理工作总结
2015/04/27 职场文书
《揠苗助长》教学反思
2016/02/20 职场文书