JS在浏览器中解析Base64编码图像


Posted in Javascript onFebruary 09, 2017

上一篇介绍中,我们将二进制文件(BLOB)保存为Base64编码的文本,这些文本可以内嵌在XML的标签中,因此二进制信息它可以随着XML文件被拷贝、下载而不用担心信息会缺失。这项技术也在email邮件中被广泛使用。

浏览器对Base64的支持

图像是最经常被使用的一种二进制文件。而现代的浏览器的进步日新月异,IE7,FireFox和其他浏览器为包括Base64在内各种编码的图像信息提供了很好的支持。因此图形信息可以以下面的形式呈现在页面中、

Java代码

<img src="data:image/gif;base64,R0lGODlhDwAPAKECAAAAzMzM///// 
wAAACwAAAAADwAPAAACIISPeQHsrZ5ModrLlN48CXF8m2iQ3YmmKqVlRtW4ML 
wWACH+H09wdGltaXplZCBieSBVbGVhZCBTbWFydFNhdmVyIQAAOw==" 
alt="Base64 encoded image" width="150" height="150"/>

这种data: URI的格式能把Base64(或其他数据)可以内嵌在image标签的属性当中(或者CSS中)。我们可以看到在大部分浏览器中的显示效果: 

JS在浏览器中解析Base64编码图像

这种做法有利有弊,好处是浏览器可以在一个连接中得到完成的页面内容,不好的地方时图像的大小会增加1/3。因此,这种内嵌的方法适合对小的图形元素比如图标、圆角等等进行处理,从而减少浏览器打开的连接数,但对大的照片、图片(量少而大)等等则不应该使用Base64编码以免影响下载速度。

为了得到刚才的Base64编码,我们将上一篇的Java修改成Struts Action,并借用了JIMI进行图形的读取和格式转换,Base64编码器则改为更普遍的Apache Commons组件,代码如下:

Java代码 

public class Base64ImageAction extends ActionSupport { 
  private final static String galleryName = "gallery"; 
 private static String parent = null; 
   private String encodeString = null; 
 public String getEncodeString() { 
  return encodeString; 
 } 
 public void setEncodeString(String encodeString) { 
  this.encodeString = encodeString; 
 } 
 private String getImageFullPath() { 
  parent = new File(this.getClass().getClassLoader().getResource( 
     File.separator).getPath()).getParent()+File.separator+"flag.jpg"; 
 } 
 public String execute() { 
  ByteArrayOutputStream output = new ByteArrayOutputStream(); 
  try { 
   JimiReader reader = Jimi.createJimiReader(this.getImageFullPath()); 
   Image image = reader.getImage(); 
   Jimi.putImage("image/png", image, output); 
   output.flush(); 
   output.close(); 
   this.encodeString = Base64.encodeBase64String(output.toByteArray()); 
  } catch (IOException e) { 
   e.printStackTrace(); 
  } catch (JimiException e) { 
   e.printStackTrace(); 
  } 
  return SUCCESS; 
 } 
}

对应的View端是个十分简单的Freemarker模板:

Html代码

<html> 
<head> 
<title>Hello,World</title> 
</head> 
<body> 
<img src="data:image/png;base64,${encodeString}" /> 
</body> 
</html>

处理古代浏览器

世界总是不是那么完美,尽管大部分现代浏览器对Base64的处理都十分完善,但是我们不能不考虑到一些“古老”的浏览器,而现在还是普遍使用的“古老”的浏览器,就当属IE6,在IE6里试图浏览上面的图片可能会得到一个红叉叉。我们不得不为IE6做一些特殊处理,利用下面的JavaScript,我们把Base64字串传回服务器端,重新解析成图片

Javascript代码 

// a regular expression to test for Base64 data 
var BASE64_DATA = /^data:.*;base64/i; 
// path to the PHP module that will decode the encoded data 
var base64Path = "/my/path/base64.php"; 
function fixBase64(img) { 
 // check the image source 
 if (BASE64_DATA.test(img.src)) { 
 // pass the data to the PHP routine 
 img.src = base64Path + "?" + img.src.slice(5); 
 } 
}; 
// fix images on page load 
onload = function() { 
 for (var i = 0; i < document.images.length; i++) { 
 fixBase64(document.images[i]); 
 } 
};

服务器端的Struts可以参考上面的例子做反向操作,具体从略。

更完美的方法

将Base64传回服务器解码是不错的IE6补丁,但是违背了我们的初衷,对IE6来说,浏览器连接数并未有任何减少。更直接的想法,是否能用Javascript直接在浏览器中,对Base64文本进行解码呢?我们构思的场景如下:服务器端先将图片转换成PNG格式以方便客户端进行处理,Base64编码之后,利用JSON将文本传递给浏览器客户端进行处理。

我们选择PNG图形格式是因为PNG已经俨然成为新的Web图形标准,它格式非常简单,可以很方便的用javascript进行处理而不需要借助浏览器的支持。我们知道javascript直接不能处理二进制数据,但是现在这不是个问题,服务器端已经准备好了Base64编码的文本数据,现在我们只需要一个javascript的Base64解析器,你可以在这里找到一个notmasteryet的Base64解析器。

现在PNG图形格式采用了DEFLATE作为唯一的压缩算法,该算法也广泛应用在ZIP,GZIP等压缩格式中。PNG图像格式文件(或者称为数据流)由一个8字节的PNG文件署名(PNG file signature)域和按照特定结构组织的3个以上的数据块(chunk)组成。

PNG定义了两种类型的数据块,一种是称为关键数据块(critical chunk),这是标准的数据块,另一种叫做辅助数据块(ancillary chunks),这是可选的数据块。关键数据块定义了4个标准数据块,其中图像数据块IDAT(image data chunk):它存储实际的数据, PNG总的数据流采用DEFLAT进行压缩。此外还擦用三角过滤“delta filters”来过滤每一行的像素的未压缩数据。DEFLAT和delta压缩在其他数据和文本处理中也被广泛应用。PNG格式你可以参考<a href="http://www.libpng.org/pub/png/spec/1.1/PNG-Contents.html">官方文档</a>。

很棒的,notmasteryet也为我们提供了一个DEFLAT解压器。

最后,我们把这些组合起来:

Html代码

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
 <title>Demo JavaScript PNG Viewer</title> 
 </head> 
<body onload="show(gravatar);"> 
<script src="../Source/Base64.js" type="text/javascript"></script> 
<script src="../Source/Deflate.js" type="text/javascript"></script> 
<script src="../Source/PNG.js" type="text/javascript"></script> 
<script type="text/javascript"> 
var gravatar = 'iVBORw0KGgoAAAANSUhEUgAAA.......数据从略......55CYII='; 
String.prototype.padRight = function(c, n){ 
 var txt = ''; 
 for(var i=0;i<n-this.length;i++) txt += c; 
 return txt + this; 
}; 
function show(data){ 
 var png = new PNG(data); 
 var img = document.getElementById('image'), limg = document.getElementById('largeimage'); 
 document.getElementById('nativeimage').src = 'data:image/png;base64,' + data; 
 img.innerHTML = ''; 
 limg.innerHTML = ''; 
 img.style.width = png.width + 'px'; 
 img.style.height = png.height + 'px'; 
 limg.style.width = (png.width * 3) + 'px'; 
 limg.style.width = (png.height * 3) + 'px'; 
 var line; 
 while(line = png.readLine()) 
 { 
  for (var x = 0; x < line.length; x++){ 
   var px = document.createElement('div'), px2 = document.createElement('div'); 
   px.className = px2.className = 'pixel'; 
   px.style.backgroundColor = px2.style.backgroundColor = '#' + line[x].toString(16).padRight('0', 6); 
   img.appendChild(px); 
   limg.appendChild(px2); 
  } 
 } 
} 
</script> 
<div id="image"></div> 
<div id="largeimage"></div> 
<img id="nativeimage" /> 
</body> 
</html>

以上所述是小编给大家介绍的JS在浏览器中解析Base64编码图像,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
HTML中Select不用Disabled实现ReadOnly的效果
Apr 07 Javascript
Jquery 实现表格颜色交替变化鼠标移过颜色变化实例
Aug 28 Javascript
Javascript中设置默认参数值示例
Sep 11 Javascript
jQuery中的编程范式详解
Dec 15 Javascript
JavaScript实现的encode64加密算法实例分析
Apr 15 Javascript
JavaScript实现将UPC转换成ISBN的方法
May 26 Javascript
jquery实现动画菜单的左右滚动、渐变及图形背景滚动等效果
Aug 25 Javascript
jquery validate demo 基础
Oct 29 Javascript
使用jQuery判断Div是否在可视区域的方法 判断div是否可见
Feb 17 Javascript
node跨域请求方法小结
Aug 25 Javascript
详解React 元素渲染
Jul 07 Javascript
vue响应式原理与双向数据的深入解析
Jun 04 Vue.js
jQuery实现在新增加的元素上添加事件方法案例分析
Feb 09 #Javascript
jquery滚动条插件slimScroll使用方法
Feb 09 #Javascript
JS回调函数简单用法示例
Feb 09 #Javascript
Bootstrap列表组学习使用
Feb 09 #Javascript
jQuery实现获取隐藏div高度的方法示例
Feb 09 #Javascript
Bootstrap进度条学习使用
Feb 09 #Javascript
详解浏览器渲染页面过程
Feb 09 #Javascript
You might like
PHP服务器页面间跳转实现方法
2012/08/02 PHP
ThinkPHP框架实现定时执行任务的两种方法分析
2018/09/04 PHP
单独使用CKFinder选择图片的方法
2010/08/21 Javascript
javascript函数以及基础写法100多条实用整理
2013/01/13 Javascript
javascript从右边截取指定字符串的三种实现方法
2013/11/29 Javascript
JS实现鼠标经过好友列表中的好友头像时显示资料卡的效果
2014/07/02 Javascript
JavaScript中遍历对象的property的3种方法介绍
2014/12/30 Javascript
jquery中toggle函数交替使用问题
2015/06/22 Javascript
跟我学习javascript的for循环和for...in循环
2015/11/18 Javascript
Web打印解决方案之证件套打的实现思路
2016/08/29 Javascript
JavaScript鼠标特效大全
2016/09/13 Javascript
AngularJS验证信息框架的封装插件用法【w5cValidator扩展插件】
2016/11/03 Javascript
js实现图片360度旋转
2017/01/22 Javascript
Vue.js学习之计算属性
2017/01/22 Javascript
详解AngularJS controller调用factory
2017/05/19 Javascript
纯js实现页面返回顶部的动画(超简单)
2017/08/10 Javascript
webpack处理 css\less\sass 样式的方法
2017/08/21 Javascript
javascript观察者模式实现自动刷新效果
2017/09/05 Javascript
详解微信UnionID作用
2019/05/15 Javascript
p5.js实现故宫橘猫赏秋图动画
2019/10/23 Javascript
使用layui前端框架弹出form表单以及提交的示例
2019/10/25 Javascript
解决$store.getters调用不执行的问题
2019/11/08 Javascript
[07:49]2014DOTA2国际邀请赛 Newbee夺冠后采访xiao8坦言奖金会上交
2014/07/23 DOTA
解决python 自动安装缺少模块的问题
2018/10/22 Python
python实现祝福弹窗效果
2019/04/07 Python
windows上安装python3教程以及环境变量配置详解
2019/07/18 Python
Pytorch中accuracy和loss的计算知识点总结
2019/09/10 Python
Python csv文件的读写操作实例详解
2019/11/19 Python
TensorBoard 计算图的查看方式
2020/02/15 Python
python datetime处理时间小结
2020/04/16 Python
django实现日志按日期分割
2020/05/21 Python
Python使用Pygame绘制时钟
2020/11/29 Python
Strawberrynet草莓网新加坡站:护肤、彩妆、香水及美发产品
2018/08/31 全球购物
澳大利亚优质葡萄酒专家:Vintage Cellars
2019/01/08 全球购物
光信息科学与技术专业职业生涯规划
2014/03/13 职场文书
党员志愿者活动总结
2014/06/26 职场文书