文章:李蕊(成都中心)

排版:陈倩

背景:

某天我收到来自公司首席设计师的一则钉钉消息:轻设计编辑器导出的图片为什么会模糊?当我看到这个问题时,脑海中不禁产生了下面的疑问:怎么会模糊呢?是不是添加到编辑器的图片本身就是模糊的?

之后根据转赠给我的“作品”在编辑器里导出后发现,问题还真存在!换作较为准确的描述应该是:导出jpeg格式的自定义小尺寸图片会导致图片上的某些组件边缘虚化(特别是文字)。

 基础概念

什么是图片?

在计算机上看到的图片可以称为“数字图像”,按存储方式可分为两种:点阵图(Bitmap)和矢量图(Vector)。这里讨论的是点阵图,点阵图又称为位图,在Photoshop里放大一张图片可以看到一个一个的“方格”,即是“像素”,位图就是由像素阵列的排列来呈现图像的。每个像素可以表达色彩的位数是不同的,色彩位数越多,可用的颜色就越多,图像越逼真。

如何界定模糊?

一种是图片本身被放大后,单位面积内精细度降低,就会失真变模糊,因为图片的像素信息是固定的(点阵图)。还有一种情况是超高分辨率电脑屏幕下查看一张图片会比在低分辨率电脑屏幕上感觉模糊,例如Retina屏幕。所以若是要在超高分辨率下保持清晰,需要把图片精细度提高才能让肉眼看上去达到舒适感。

生成图片的原理是什么(dom-to-image源码分析)?

1. 整体思路

step1:利用XMLSerializer的serializeToString()构造一个字符串,以XML形式表示指定的DOM树

step2:利用SVG的将来自不同XML名称空间的元素包含进去,这里指上面的(X)HTML

step3:将SVG转为CANVAS

step4:利用HTMLCanvasElement.toDataURL() 生成不同格式的图片文件

2. 关键函数

3. 特殊处理

将DOM转换成XMLString之前,还需要处理字体文件和图片,通过ajax下载成blob数据再转换成base64以解决跨域问题。首先通过getComputedStyle(node)可以获取Node的样式,找出fontFamily和图片src,再查找字体的文件地址。

通过document.styleSheets获取样式表数组,注意根据每个CSSOM样式表接口的ownerNode属性区分其可读性,见下图:

  • ownerNode.tagName === 'STYLE'  则cssRules 可读取  内部样式表

  • ownerNode.tagName === 'LINK'  则cssRules 不可读取  外部样式表

获取cssRules后,根据type === CSSRule.FONT_FACE_RULE 找到字体样式,从而获取字体文件路径,匹配对应的fontFamily对应的字体即是需要下载的。见下图:

最后一步替换htmlStr里的字体和图片的url为base64格式,大体流程及完成。一些浏览器兼容性问题一并考虑,篇幅关系这里就不一一讲解了。

生成图片的关键在于:将 htmlStr塞到svg里,转换成svg,再将 svg 转换成 canvas

SVG的元素允许包含不同的XML命名空间。在浏览器的上下文中,就是我们的Xhtml, 极具包容性的接收了它

最后通过blob2base64把svg转换到canvas里,生成图片

生成图片的格式

canvas生成后,可以通过toDataURL() 转为不同格式的图片。下面是常见的两种图片格式:

  • PNG格式: 便携式网络图形,无损压缩的位图图形格式,带有alpha通道。

  • JPEG格式:JPEG是常见的一种格式,有损压缩,以去除冗余的图像和彩色数据获取极高的压缩率,用以减小图片大小。

解决方案

清楚了上面的基础知识,我对前端生成图片有了大致的概念,接下来是定位“模糊”原因。分别导出 png格式和jpeg格式图片,发现只有jpeg格式才会出现边缘模糊,如下图:

因为相同的canvas数据导出的图片却因为格式不同效果不同,怀疑 jpeg格式边缘模糊有可能是因为图片质量被压缩了。那么canvas转成不同格式的图片质量是如何控制的呢?在MDN上可以找到答案:

官方解释:

即使在清贫的岁月,也不能失去对幸福美好的向往,那些摆脱平庸的梦总能编制我们简单的生活,为我们简单的时光点缀希望。不能说我们总要多热爱生活,但总要有一颗懂得欣赏和珍惜的心。

由此可见,导出png格式的图片是没有质量参数的,而导出jpeg格式的图片是有质量参数可设置的,而且默认是0.92。经过测试,当质量参数设置为1.0时,质量最好,导出效果与png一致。

下图是质量为0.1和1.0的效果对比:

总  结

前端canvas生成图片的整体流程和思路就是上述所讲,最后通过优化jpeg格式导出的质量参数解决了模糊的问题,如有不同观点和方案可以留言进行讨论。

想要了解更多技术知识

快来关注我们吧

java blob转为图片_导出的图片为什么会糊?!相关推荐

  1. js小学生图片_我是小学生图片

    我是小学生啦正文:双岗小学 1(3)班 曹思曼 8月31日是我开学的第一天,妈妈送我去上学.到了校圆,我看到了教室里一排排的桌子,一个座位上坐两个小朋友,这可和幼儿圆里不一样了.班主任老师给我们每个人 ...

  2. xsd文件转图片_如何将图片转化为PDF格式?分享一个超简单的方法给你

    如何将图片转化为PDF格式?有些朋友经常需要将图片转换成PDF格式文件,这样比较方便保存和传输.熟悉文件转换的朋友是知道该怎么操作的,不了解的朋友不用担心,今天我来教大家一个方法,能够帮助我们简单快速 ...

  3. python程序代码图片_完整的图片去噪代码(python)

    #coding:utf-8 import sys,os from PIL import Image,ImageDraw #二值判断,如果确认是噪声,用改点的上面一个点的灰度进行替换 #该函数也可以改成 ...

  4. java 生成 word文档 导出附带图片 已实现

    思路: 利用模板来实现. 第一步:新建一个word,需要替换的内容用${replace}来做标记,图片的话直接将需要附带上的图先贴上去, 第二步: 然后保存为xml类型文件, 然后编辑器打开, 然后将 ...

  5. java程序顶层显示图片_如何让图片以半透明的效果显示在全部程序或窗口的最上层?...

    还可以试试这个 1.给立方体设置一个背景,进入 CompizConfig -> 桌面立方体 -> Appearance -> Skydome 勾选 "Background& ...

  6. mysql 图片转为二进制_如何把图片转换成二进制存入数据库

    public static byte[] imgBytesIn;//用来存储图片的二进制 Stream ms; byte[] picbyte; //在创建数据库链接,测试链接成功后,在高级里可自动生成 ...

  7. 微信缓存dat怎么转图片_微信 .dat图片格式转换为.jpg

    异或,英文为exclusive OR,缩写成xor 异或(xor)是一个数学运算符.它应用于逻辑运算.异或的数学符号为"⊕",计算机符号为"xor".异或也叫半 ...

  8. ashx返回图片_显示ashx图片

    ascx aspx ashx asmx 文件的作用 ascx aspx ashx asmx 文件的作用 ascx: Ascx 是给予Web的用户控件(UserControl),一般是用来重用的,不能直 ...

  9. 爬虫requests如何提取图片_如何提取图片上的文字(办公技巧)

    是夜,公寓里,一道黑影闪过窗前,对面楼顶传来一声凄厉的猫叫声. 王美丽一个机灵,目中闪过一丝恐惧. 她面前的电脑里,正在播放<午夜凶铃>. 阴森恐怖的配音,让她全身发冷,感觉后脊梁有一股凉 ...

最新文章

  1. 不同浏览器的怪癖小结【转】
  2. huggingface实操_盘点2018年度GtiHub开源项目TOP 25
  3. MMD_6b_DecisionTree
  4. 现代软件工程 第十六章 【IT 行业的创新】练习与讨论
  5. Shell 显示带颜色字体
  6. PM2 node进程管理工具 自动部署小结
  7. hdu 1565 方格取数(1)
  8. SQL注入绕过登录验证
  9. 用C#写 四舍五入函数(原理版)
  10. 交换两个数组 差最小 java_如何交换两个等长整形数组使其数组和的差最小(C和java实现)...
  11. 视觉SLAM笔记(39) 求解 ICP
  12. Linux高性能网络:协程系列01-前言
  13. java 新手入门级项目(家庭收支记账软件)
  14. 即时聊天通讯软件安卓+ios双端原生源码
  15. 微信公众号排查“该公众号提供的服务出现故障,请稍后再试”问题
  16. oracle 11g失败,求助,oracle 11g 启动失败,求大神帮忙看看,谢谢
  17. 读书笔记(八)--货币战争 金权天下
  18. 新手小白用C# winform 读取Excel表
  19. 智能车摄像头算法——寻线
  20. 领悟《信号与系统》之 信号与系统概论

热门文章

  1. Spring 环境搭建与IOC HelloWorld
  2. android sha1和签名证书的学习
  3. 基于JAVA+SpringMVC+Mybatis+MYSQL的在线学习管理系统源码
  4. SQL Server 2008中SQL之WaitFor
  5. C#使用CurrentUICulture切换语言
  6. MVC5应用程序目录
  7. POJ 2777 线段树
  8. 通过反射获取类的所有属性和方法
  9. 52 - LeetCode-13 -罗马数字转整数_罗马数字转数字
  10. java字符类型的返回值,Java字符类isWhitespace()方法及示例