处理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 相关文章推荐
jQuery 扩展对input的一些操作方法
Oct 30 Javascript
预加载css或javascript的js代码
Apr 23 Javascript
Angular用来控制元素的展示与否的原生指令介绍
Jan 07 Javascript
Javascript中arguments对象的详解与使用方法
Oct 04 Javascript
JS模拟实现ECMAScript5新增的数组方法
Mar 20 Javascript
jQuery操作css样式
May 15 jQuery
angular使用post、get向后台传参的问题实例
May 27 Javascript
Express框架之connect-flash详解
May 31 Javascript
解决Jstree 选中父节点时被禁用的子节点也会选中的问题
Dec 27 Javascript
js实现微信/QQ直接跳转到支付宝APP打开口令领红包功能
Jan 09 Javascript
JS中FormData类实现文件上传
Mar 27 Javascript
Vue.js中v-bind指令的用法介绍
Mar 13 Vue.js
介绍一下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
javascript getElementsByTagName
2011/01/31 Javascript
js使浏览器窗口最大化实现代码(适用于IE)
2013/08/07 Javascript
JS 有趣的eval优化输入验证实例代码
2013/09/22 Javascript
node.js中的http.response.addTrailers方法使用说明
2014/12/14 Javascript
jquery插件pagination实现无刷新ajax分页
2015/09/30 Javascript
jquery实现二级导航下拉菜单效果
2015/12/18 Javascript
js轮播图代码分享
2016/07/14 Javascript
vue实现长图垂直居上 vue实现短图垂直居中
2017/10/18 Javascript
Vue实现内部组件轮播切换效果的示例代码
2018/04/07 Javascript
从零开始在NPM上发布一个Vue组件的方法步骤
2018/12/20 Javascript
taro开发微信小程序的实践
2019/05/21 Javascript
微信小程序实现多选框功能的实例代码
2020/06/24 Javascript
js实现随机点名器精简版
2020/06/29 Javascript
[03:16]DOTA2完美大师赛小组赛精彩集锦
2017/11/22 DOTA
解决Python中字符串和数字拼接报错的方法
2016/10/23 Python
python 列表,数组和矩阵sum的用法及区别介绍
2018/06/28 Python
为什么str(float)在Python 3中比Python 2返回更多的数字
2018/10/16 Python
Python一句代码实现找出所有水仙花数的方法
2018/11/13 Python
使用Python将字符串转换为格式化的日期时间字符串
2019/09/01 Python
Django通过dwebsocket实现websocket的例子
2019/11/15 Python
python GUI库图形界面开发之PyQt5菜单栏控件QMenuBar的详细使用方法与实例
2020/02/28 Python
keras实现theano和tensorflow训练的模型相互转换
2020/06/19 Python
Python根据字典的值查询出对应的键的方法
2020/09/30 Python
使用phonegap克隆和删除联系人的实现方法
2017/03/31 HTML / CSS
香港网上花店:FlowerAdvisor香港
2019/05/30 全球购物
JAVA程序设计笔试题面试题一套
2015/07/28 面试题
趣味体育活动方案
2014/02/08 职场文书
计算机通信专业推荐信
2014/02/22 职场文书
《记金华的双龙洞》教学反思
2014/04/19 职场文书
2014年党的群众路线教育实践活动总结
2014/04/25 职场文书
门面房租房协议书
2014/12/01 职场文书
2015会计试用期工作总结
2014/12/12 职场文书
小学重阳节活动总结
2015/03/24 职场文书
自主招生自荐信格式范文
2015/03/25 职场文书
Java数据开发辅助工具Docker与普通程序使用方法
2021/09/15 Java/Android
Python IO文件管理的具体使用
2022/03/20 Python