处理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模仿苹果桌面的Dock效果(初级版)
Oct 15 Javascript
Jquery实现显示和隐藏的4种简单方式
Aug 28 Javascript
js同比例缩放图片的小例子
Oct 30 Javascript
Node.js项目中调用JavaScript的EJS模板库的方法
Mar 11 Javascript
js中删除数组中的某一元素实例(无下标时)
Feb 28 Javascript
JavaScript实现动态增删表格的方法
Mar 09 Javascript
细说webpack源码之compile流程-入口函数run
Dec 26 Javascript
vue移动端UI框架实现QQ侧边菜单组件
Mar 09 Javascript
JavaScript原型链与继承操作实例总结
Aug 24 Javascript
javaScript中indexOf用法技巧
Nov 26 Javascript
vue 项目@change多个参数传值多个事件的操作
Jan 29 Vue.js
JavaScript+HTML实现学生信息管理系统
Apr 20 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 pthreads多线程的安装与使用
2016/01/19 PHP
PHP优化之批量操作MySQL实例分析
2020/04/23 PHP
Prototype 1.5.0_rc1 及 Prototype 1.5.0 Pre0小抄本
2006/09/22 Javascript
Jquery CheckBox全选方法代码附js checkbox全选反选代码
2010/06/09 Javascript
js querySelector和getElementById通过id获取元素的区别
2012/04/20 Javascript
Node.js开发指南中的简单实例(mysql版)
2013/09/17 Javascript
简单常用的幻灯片播放实现代码
2013/09/25 Javascript
JavaScript使用循环和分割来替换和删除元素实例
2014/10/13 Javascript
2014年50个程序员最适用的免费JQuery插件
2014/12/15 Javascript
jquery 判断是否支持Placeholder属性的方法
2017/02/07 Javascript
浅谈NodeJs之数据库异常处理
2017/10/25 NodeJs
webpack多入口文件页面打包配置详解
2018/01/09 Javascript
vue中设置height:100%无效的问题及解决方法
2018/07/27 Javascript
webuploader分片上传的实现代码(前后端分离)
2018/09/10 Javascript
有趣的JavaScript隐式类型转换操作实例分析
2020/05/02 Javascript
如何使用jQuery操作Cookies方法解析
2020/09/08 jQuery
[01:21:58]守擂赛DOTA2第一周决赛
2020/04/22 DOTA
Python用字典构建多级菜单功能
2019/07/11 Python
复化梯形求积分实例——用Python进行数值计算
2019/11/20 Python
Django ForeignKey与数据库的FOREIGN KEY约束详解
2020/05/20 Python
Opencv求取连通区域重心实例
2020/06/04 Python
用python进行视频剪辑
2020/11/02 Python
python录音并调用百度语音识别接口的示例
2020/12/01 Python
matplotlib相关系统目录获取方式小结
2021/02/03 Python
极简的HTML5模版
2015/07/09 HTML / CSS
华丽的手绘陶瓷:MacKenzie-Childs
2017/02/04 全球购物
加拿大票务网站:Ticketmaster加拿大
2017/07/17 全球购物
女方回门宴答谢词
2014/01/14 职场文书
护士见习期自我鉴定
2014/02/08 职场文书
给学校的建议书范文
2014/05/15 职场文书
2014中考励志标语
2014/06/05 职场文书
体现团队精神的口号
2014/06/06 职场文书
关于国庆节的演讲稿
2014/09/05 职场文书
详解MySQL InnoDB存储引擎的内存管理
2021/04/08 MySQL
「魔导具师妲莉亚永不妥协~从今天开始的自由职人生活~」1、2卷发售宣传CM公开
2022/03/21 日漫
利用正则表达式匹配浮点型数据
2022/05/30 Java/Android