处理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 相关文章推荐
基于mootools 1.3框架下的图片滑动效果代码
Apr 22 Javascript
js切换div css注意的细节
Dec 10 Javascript
屏蔽网页右键复制和ctrl+c复制的js代码
Jan 04 Javascript
JS获取数组最大值、最小值及长度的方法
Nov 24 Javascript
AngularJs html compiler详解及示例代码
Sep 01 Javascript
js案例之鼠标跟随jquery版(实例讲解)
Jul 21 jQuery
webpack4 + react 搭建多页面应用示例
Aug 03 Javascript
JavaScript继承的特性与实践应用深入详解
Dec 30 Javascript
基于原生js实现九宫格算法代码实例
Jul 03 Javascript
Ajax获取node服务器数据的完整步骤
Sep 20 Javascript
jquery插件实现轮播图效果
Oct 19 jQuery
JavaScript实现班级抽签小程序
May 19 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
咖啡的传说和历史
2021/03/03 新手入门
php 随机数的产生、页面跳转、件读写、文件重命名、switch语句
2009/08/07 PHP
PHP生成json和xml类型接口数据格式
2015/05/17 PHP
PHP实现可精确验证身份证号码的工具类示例
2018/05/31 PHP
基于Jquery的表格隔行换色,移动换色,点击换色插件
2010/12/22 Javascript
jquery select多选框的左右移动 具体实现代码
2013/07/03 Javascript
JS获取IP、MAC和主机名的五种方法
2013/11/14 Javascript
js实现用户离开页面前提示是否离开此页面的方法(包括浏览器按钮事件)
2015/07/18 Javascript
javascript实现网页端解压并查看zip文件
2015/12/15 Javascript
JavaScript中的数组遍历forEach()与map()方法以及兼容写法介绍
2016/05/19 Javascript
微信小程序实现给循环列表添加点击样式实例
2017/04/26 Javascript
详解vue-router 2.0 常用基础知识点之router.push()
2017/05/10 Javascript
JS实现多张图片预览同步上传功能
2017/06/23 Javascript
在iframe中使bootstrap的模态框在父页面弹出问题
2017/08/07 Javascript
JS实现身份证输入框的输入效果
2017/08/21 Javascript
实例教学如何写vue插件
2017/11/30 Javascript
仿京东快报向上滚动的实例
2017/12/13 Javascript
laravel5.3 vue 实现收藏夹功能实例详解
2018/01/21 Javascript
jQuery动态生成的元素绑定事件操作实例分析
2019/05/04 jQuery
Vue执行方法,方法获取data值,设置data值,方法传值操作
2020/08/05 Javascript
[02:31]《DAC最前线》之选手酒店现场花絮
2015/01/30 DOTA
python在linux中输出带颜色的文字的方法
2014/06/19 Python
Python捕捉和模拟鼠标事件的方法
2015/06/03 Python
在java中如何定义一个抽象属性示例详解
2017/08/18 Python
利用python对Excel中的特定数据提取并写入新表的方法
2018/06/14 Python
Python使用pymysql从MySQL数据库中读出数据的方法
2018/07/25 Python
Python 使用多属性来进行排序
2019/09/01 Python
Python浮点数四舍五入问题的分析与解决方法
2019/11/19 Python
解决Numpy中sum函数求和结果维度的问题
2019/12/06 Python
Python 基于FIR实现Hilbert滤波器求信号包络详解
2020/02/26 Python
用python绘制樱花树
2020/10/09 Python
娇韵诗Clarins意大利官方网站:法国天然护肤品牌
2020/03/11 全球购物
汉语言文学毕业生求职信
2013/10/01 职场文书
财务工作犯错检讨书
2014/10/07 职场文书
职场新人刚入职工作总结该怎么写?
2019/05/15 职场文书
Go 自定义package包设置与导入操作
2021/05/06 Golang