处理canvas绘制图片模糊问题


Posted in Javascript onMay 11, 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绘制图片模糊图片问题处理的详细内容!

 

Tags in this post...

Javascript 相关文章推荐
JavaScript判断两种格式的输入日期的正确性的代码
Mar 25 Javascript
jquery ajax return没有返回值的解决方法
Oct 20 Javascript
JS文本框追加多个下拉框的值的简单实例
Jul 12 Javascript
利用JS解决ie6不支持max-width,max-height问题的方法
Jan 02 Javascript
Javascript之Number对象介绍
Jun 07 Javascript
javaScript给元素添加多个class的简单实现
Jul 20 Javascript
jQuery搜索框效果实现代码(百度关键词联想)
Feb 25 Javascript
关于axios返回空对象的问题解决
Apr 04 Javascript
分析javascript中9 个常见错误阻碍你进步
Sep 18 Javascript
微信浏览器下拉黑边解决方案 wScroollFix
Jan 21 Javascript
JS中多层次排序算法的实现代码
Jan 06 Javascript
JS前端使用Canvas快速实现手势解锁特效
Sep 23 Javascript
介绍一下28个JS常用数组方法
May 06 #Javascript
VUE解决跨域问题Access to XMLHttpRequest at
js判断两个数组相等的5种方法
May 06 #Javascript
vue使用watch监听属性变化
Apr 30 #Vue.js
vue-cli3.x配置全局的scss的时候报错问题及解决
vue项目如何打包之项目打包优化(让打包的js文件变小)
关于vue-router-link选择样式设置
Apr 30 #Vue.js
You might like
php出现Cannot modify header information问题的解决方法大全
2008/04/09 PHP
PHP实现时间轴函数代码
2011/10/08 PHP
探讨GDFONTPATH能否被winxp下的php支持
2013/06/21 PHP
浅析Yii2 GridView 日期格式化并实现日期可搜索教程
2016/04/22 PHP
CodeIgniter框架验证码类库文件与用法示例
2017/03/18 PHP
PHP设计模式之适配器模式定义与用法详解
2018/04/03 PHP
70+漂亮且极具亲和力的导航菜单设计国外网站推荐
2011/09/20 Javascript
js的延迟执行问题分析
2014/06/23 Javascript
基于jQuery实现的图片切换焦点图整理
2014/12/07 Javascript
jquery插件corner实现圆角边框的方法
2015/03/09 Javascript
javascript数组去重方法汇总
2015/04/23 Javascript
js enter键激发事件实例代码
2016/08/17 Javascript
yarn与npm的命令行小结
2016/10/20 Javascript
JS正则匹配URL网址的方法(可匹配www,http开头的一切网址)
2017/01/06 Javascript
详解vue-router 2.0 常用基础知识点之导航钩子
2017/05/10 Javascript
基于JavaScript实现多级菜单效果
2017/07/25 Javascript
关于JavaScript语句后面的分号问题
2017/12/07 Javascript
微信小程序中this.data与this.setData的区别详解
2018/09/17 Javascript
用Vue编写抽象组件的方法
2019/05/06 Javascript
web.py中调用文件夹内模板的方法
2014/08/26 Python
Python中为feedparser设置超时时间避免堵塞
2014/09/28 Python
Python入门篇之函数
2014/10/20 Python
Django添加favicon.ico图标的示例代码
2018/08/07 Python
详解Python中is和==的区别
2019/03/21 Python
pycharm 批量修改变量名称的方法
2019/08/01 Python
selenium+python实现自动登陆QQ邮箱并发送邮件功能
2019/12/13 Python
基于python实现生成指定大小txt文档
2020/07/20 Python
Python远程linux执行命令实现
2020/11/11 Python
html5新特性与用法大全
2018/09/13 HTML / CSS
html5模拟平抛运动(模拟小球平抛运动过程)
2013/07/25 HTML / CSS
十佳家长事迹材料
2014/08/26 职场文书
迎国庆演讲稿
2014/09/15 职场文书
入股合作协议书
2014/10/12 职场文书
MySQL时间设置注意事项的深入总结
2021/05/06 MySQL
Python - 10行代码集2000张美女图
2021/05/23 Python
健身房被搭讪?用python写了个小米计时器助人为乐
2021/06/08 Python