面试中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 相关文章推荐
可以文本显示的公告栏的js代码
Mar 11 Javascript
javascript 窗口加载蒙板 内嵌网页内容
Nov 19 Javascript
JavaScript flash复制库类 Zero Clipboard
Jan 17 Javascript
JavaScript实现同一页面内两个表单互相传值的方法
Aug 12 Javascript
avalon js实现仿微博拖动图片排序
Aug 14 Javascript
如何用js判断dom是否有存在某class的值
Feb 13 Javascript
微信小程序实战之登录页面制作(5)
Mar 30 Javascript
vuejs使用FormData实现ajax上传图片文件
Aug 08 Javascript
js实现数组和对象的深浅拷贝
Sep 30 Javascript
AngularJS 中的数据源的循环输出
Oct 12 Javascript
vue项目中使用vue-i18n报错的解决方法
Jan 13 Javascript
layui内置模块layim发送图片添加加载动画的方法
Sep 23 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编程最快明白》第六讲:Mysql数据库操作
2010/11/01 PHP
PHP防止跨域提交表单
2013/11/01 PHP
php实现数据库的增删改查
2017/02/26 PHP
PHP 文件上传限制问题
2019/09/01 PHP
Thinkphp 框架扩展之驱动扩展实例分析
2020/04/27 PHP
通过JAVAScript实现页面自适应
2007/01/19 Javascript
js鼠标左右键 键盘值小结
2010/06/11 Javascript
8个超棒的学习 jQuery 的网站 推荐收藏
2011/04/02 Javascript
JS常用正则表达式总结
2013/11/12 Javascript
jquery实现checkbox 全选/全不选的通用写法
2014/02/22 Javascript
JS实现自适应高度表单文本框的方法
2015/02/25 Javascript
深入理解JavaScript系列(26):设计模式之构造函数模式详解
2015/03/03 Javascript
js实现简单折叠、展开菜单的方法
2015/08/28 Javascript
详解JavaScript中的4种类型识别方法
2015/09/14 Javascript
jQuery flip插件实现的翻牌效果示例【附demo源码下载】
2016/09/20 Javascript
详解Nodejs内存治理
2018/05/13 NodeJs
JS实现仿微信支付弹窗功能
2018/06/25 Javascript
详解vue中使用protobuf踩坑记
2019/05/07 Javascript
vue下使用nginx刷新页面404的问题解决
2019/08/02 Javascript
vue.js实现三级菜单效果
2019/10/19 Javascript
vue使用video插件vue-video-player的示例
2020/10/03 Javascript
JS使用setInterval计时器实现挑战10秒
2020/11/08 Javascript
python文件和目录操作方法大全(含实例)
2014/03/12 Python
Django实现表单验证
2018/09/08 Python
python2 中 unicode 和 str 之间的转换及与python3 str 的区别
2019/07/25 Python
Python之Numpy的超实用基础详细教程
2019/10/23 Python
Python3监控windows,linux系统的CPU、硬盘、内存使用率和各个端口的开启情况详细代码实例
2020/03/18 Python
Python如何在main中调用函数内的函数方式
2020/06/01 Python
纽约州一群才华横溢的金匠制作而成:Hearth Jewelry
2019/03/22 全球购物
Python里面search()和match()的区别
2016/09/21 面试题
新闻学专业大学生职业生涯规划范文
2014/03/02 职场文书
预备党员入党自我评价范文
2014/03/10 职场文书
个性婚礼策划方案
2014/05/17 职场文书
党支部四风整改方案
2014/10/25 职场文书
教师党员自我评价2015
2015/03/04 职场文书
面试提问mysql一张表到底能存多少数据
2022/03/13 MySQL