面试中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 相关文章推荐
ajax无刷新动态调用股票信息(改良版)
Nov 01 Javascript
js点击文本框后才加载验证码实例代码
Oct 20 Javascript
Express实现前端后端通信上传图片之存储数据库(mysql)傻瓜式教程(二)
Dec 10 Javascript
微信小程序 条件渲染详解
Oct 09 Javascript
基于Javascript实现的不重复ID的生成器
Dec 25 Javascript
xmlplus组件设计系列之路由(ViewStack)(7)
May 02 Javascript
浅析JS抽象工厂模式
Dec 14 Javascript
JS中判断某个字符串是否包含另一个字符串的五种方法
May 03 Javascript
Javascript中绑定click事件的四种方式介绍
Oct 26 Javascript
vue-router判断页面未登录自动跳转到登录页的方法示例
Nov 04 Javascript
微信小程序学习总结(四)事件与冒泡实例分析
Jun 04 Javascript
vue如何搭建多页面多系统应用
Jun 17 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
锁定年轻人的双倍活力 星巴克推出星倍醇即饮浓咖啡
2021/03/03 咖啡文化
PHP5+UTF8多文件上传类
2008/10/17 PHP
php 删除一个数组中的某个值.兼容多维数组!
2012/02/18 PHP
php 检查电子邮件函数(自写)
2014/01/16 PHP
php中利用explode函数分割字符串到数组
2014/02/08 PHP
PHP大文件分割上传 PHP分片上传
2017/08/28 PHP
实现JavaScript中继承的三种方式
2009/10/16 Javascript
JavaScript 自动分号插入(JavaScript synat:auto semicolon insertion)
2009/11/04 Javascript
Ext JS 4实现带week(星期)的日期选择控件(实战二)
2013/08/21 Javascript
js实现点击添加一个input节点
2014/12/05 Javascript
angular.element方法汇总
2015/01/07 Javascript
JScript中的条件注释详解
2015/04/24 Javascript
jquery实现向下滑出的二级导航下滑菜单效果
2015/08/25 Javascript
Bootstrap每天必学之滚动监听
2016/03/16 Javascript
js中用cssText设置css样式的简单方法
2016/09/19 Javascript
js实现界面向原生界面发消息并跳转功能
2016/11/22 Javascript
Bootstrap基本组件学习笔记之下拉菜单(7)
2016/12/07 Javascript
浅析JavaScript的几种Math函数,random(),ceil(),round(),floor()
2016/12/22 Javascript
Ionic2调用本地SQlite实例
2017/04/22 Javascript
bootstrap fileinput实现文件上传功能
2017/08/23 Javascript
实例解析Vue.js下载方式及基本概念
2018/05/11 Javascript
Vue项目中使用jquery的简单方法
2019/05/16 jQuery
js判断一个对象是数组(函数)的方法实例
2019/12/19 Javascript
[00:26]TI7不朽珍藏III——冥界亚龙不朽展示
2017/07/15 DOTA
详解在Python程序中使用Cookie的教程
2015/04/30 Python
Python实现抓取网页生成Excel文件的方法示例
2017/08/05 Python
Python微信库:itchat的用法详解
2017/08/14 Python
Python利用lxml模块爬取豆瓣读书排行榜的方法与分析
2019/04/15 Python
python实现连连看辅助(图像识别)
2020/03/25 Python
HTML5中视频音频的使用详解
2017/07/07 HTML / CSS
Herve Leger官网:标志性绷带连衣裙等
2018/12/26 全球购物
污水厂厂长岗位职责
2014/01/04 职场文书
护士在校生自荐信
2014/02/01 职场文书
准备去美国留学,那么大学申请文书应该怎么写?
2019/08/12 职场文书
JS 基本概念详细介绍
2021/10/16 Javascript
vue.js 使用原生js实现轮播图
2022/04/26 Vue.js