js对图片base64编码字符串进行解码并输出图像示例


Posted in Javascript onMarch 17, 2014
<!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> 

<meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> 

<style> 

body{padding-left:75px;background-color:beige} 

</style> 

<script> 

/////////////////////////// 

//base64编码的GIF图像解码 

//By Mozart0 

//2005/10/29 

//////////////////// 
//建立GIF类的对象 

//类GIF在此函数内部定义 

//str64:gif文件的Base64编码字符串 

//成功返回创建的GIF对象 

//失败返回null 

function getGif(str64){ 

var bytes=decodeBase64(str64); 

if(!bytes){ 

alert("错误:无效的Base64编码"); 

return null; 

} 

var gif=new GIF(); 

for(var i=0;i<6;i++) 

gif.version+=String.fromCharCode(bytes[i]); 

if(gif.version.slice(0,3)!="GIF"){ 

alert("错误:非Gif图像格式"); 

return null; 

} 

gif.width=bytes[i]|(bytes[i+1]<<8); 

gif.height=bytes[i+2]|(bytes[i+3]<<8); 

var f=bytes[i+4]; 

gif.colorResolution=(f>>4&0x7)+1; 

gif.sorted=(f&0x8)?true:false; 

gif.backgroundIndex=bytes[i+5]; 

gif.pixelAspectRadio=bytes[i+6]; 

if(f&0x80){ 

gif.globalPalette=[]; 

i+=getPalette(i+7,bytes,gif.globalPalette,2<<(f&0x7)); 

} 

i+=7; 

for(var j=i;j<bytes.length;j++) 

if(bytes[j]==0x21&&bytes[j+1]==0xf9) 

break; 

if(j==bytes.length){ 

for(;i<bytes.length;i++) 

if(bytes[i]==0x2c) 

break; 

if(i==bytes.length){ 

alert("错误:找不到图像数据"); 

return null; 

} 

var f=new GIF_Frame(); 

if(!getSingleFrame(i,f)) 

return null; 

else 

gif.frames.push(f); 

} 

else{ 

i=j; 

do{ 

var f=new GIF_Frame(); 

var t=getSingleFrame(i,f); 

if(!t) 

return null; 

gif.frames.push(f); 

for(i+=t;i<bytes.length;i++) 

if(bytes[i]==0x21&&bytes[i+1]==0xf9) 

break; 

} 

while(i<bytes.length); 

} 

return gif; 

//内部过程,生成色表 

function getPalette(pos,s,d,len){ 

len*=3; 

for(var i=pos;i<pos+len;i+=3) 

d.push('#'+(s[i]<=0xf?"0":"")+s[i].toString(16) 

+(s[i+1]<=0xf?"0":"")+s[i+1].toString(16) 

+(s[i+2]<=0xf?"0":"")+s[i+2].toString(16)); 

return len; 

} 

//内部过程,整合数据段 

function getBlock(pos,s,d){ 

var p=pos; 

while(len=s[p++]){ 

for(var i=0;i<len;i++) 

d.push(s[p+i]); 

p+=len; 

} 

return p-pos; 

} 

//内部过程,获取一帧数据 

function getSingleFrame(pos,frame){ 

var i=pos; 

if(bytes[i]==0x21){ 

i+=3; 

if(bytes[i]&1) 

frame.transparentIndex=bytes[i+3]; 

frame.delay=bytes[i+1]|(bytes[i+2]<<8); 

for(i+=5;i<bytes.length&&bytes[i]!=0x2c;i++); 

if(i==bytes.length){ 

alert("错误:找不到图像标志符"); 

return 0; 

} 

} 

frame.offsetX=bytes[i+1]|(bytes[i+2]<<8); 

frame.offsetY=bytes[i+3]|(bytes[i+4]<<8); 

frame.width=bytes[i+5]|(bytes[i+6]<<8); 

frame.height=bytes[i+7]|(bytes[i+8]<<8); 

var f=bytes[i+9]; 

i+=10; 

if(f&0x40) 

frame.interlace=true; 

if(f&0x20) 

frame.sorted=true; 

if(f&0x80){ 

frame.colorResolution=(f&0x7)+1; 

frame.localPalette=[]; 

i+=getPalette(i,bytes,frame.localPalette,1<<frame.colorResolution); 

} 

else{ 

frame.colorResolution=gif.colorResolution; 

frame.localPalette=gif.globalPalette; 

} 

var lzwLen=bytes[i++]+1; 

i+=getBlock(i,bytes,frame.data); 

frame.data=decodeLzw(frame.data,lzwLen); 

return frame.data?i-pos:0; 

} 

//定义存储GIF文件的数据结构 

//提供方法showInfo,返回图片信息 

function GIF(){ 

this.version=""; //版本号 

this.width=0; //逻辑屏幕宽度 

this.height=0; //逻辑屏幕高度 

this.colorResolution=0; //颜色深度 

this.sorted=false; //全局色表分类标志 

this.globalPalette=null; //全局色表 

this.backgroundIndex=-1; //背景色索引 

this.pixelAspectRadio=0; //像素宽高比 

this.frames=[]; //图像各帧,见GIF_Frame 

this.showInfo=function(sep){ //显示图片信息,sep为行分隔符 

if(!sep) 

sep="\n"; 

var s="Gif infomation:"+sep+"-------------------"; 

s+=subInfo(this)+sep; 

for(var i=0;i<this.frames.length;i++) 

s+=sep+"frames "+i+"----------"+subInfo(this.frames[i]); 

return s; 

function subInfo(o){ 

var s=""; 

for(var i in o){ 

if(i=="showInfo"||i=="draw") 

continue; 

s+=sep+i+":"; 

if(typeof(o[i])=="object") 

s+=(o[i]?o[i].length:"null"); 

else 

s+=o[i]; 

} 

return s; 

} 

} 

} 

//定义存储一帧图象的数据结构 

//提供方法draw,绘图 

function GIF_Frame(){ 

this.offsetX=0; //X方向偏移量 

this.offsetY=0; //Y方向偏移量 

this.width=0; //图象宽度 

this.height=0; //图象高度 

this.localPalette=null; //局部色表 

this.colorResolution=0; //颜色深度 

this.interlace=false; //交错标志 

this.sorted=false; //局部色表分类标志 

this.data=[]; //图像数据,存储各像素颜色的整数索引 

this.transparentIndex=-1; //透明色索引 

this.delay=0; //帧延时 

this.draw=function(parent,zoom){ 

if(!this.data.length) 

return; 

if(!parent) 

parent=document.body; 

if(!zoom) 

zoom=1; 

if(parent.clientWidth<this.width*zoom) 

parent.style.width=this.width*zoom; 

if(parent.clientHeight<this.height*zoom) 

parent.style.height=this.height*zoom; 

var id="ImgDefaultDraw"; 

var img=document.getElementById(id); 

if(img) 

delete parent.removeChild(img); 

img=document.createElement("DIV"); 

img.id=id; 

parent.appendChild(img); 

img.style.position="absolute"; 

var t=document.createElement("DIV"); 

t.style.overflow="hidden"; 

t.style.position="absolute"; 

defLayout(this.data,this.localPalette,this.width,this.height,img,t,zoom); 

delete t; 

} 

} 

} 

//Base64解码 

//strIn,输入字符串 

//成功返回一个数组,每一个元素包含一字节信息 

//失败返回null 

function decodeBase64(strIn){ 

if(!strIn.length||strIn.length%4) 

return null; 

var str64= 

"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; 

var index64=[]; 

for(var i=0;i<str64.length;i++) 

index64[str64.charAt(i)]=i; 

var c0,c1,c2,c3,b0,b1,b2; 

var len=strIn.length; 

var len1=len; 

if(strIn.charAt(len-1)=='=') 

len1-=4; 

var result=[]; 

for(var i=0,j=0;i<len1;i+=4){ 

c0=index64[strIn.charAt(i)]; 

c1=index64[strIn.charAt(i+1)]; 

c2=index64[strIn.charAt(i+2)]; 

c3=index64[strIn.charAt(i+3)]; 

b0=(c0<<2)|(c1>>4); 

b1=(c1<<4)|(c2>>2); 

b2=(c2<<6)|c3; 

result.push(b0&0xff); 

result.push(b1&0xff); 

result.push(b2&0xff); 

} 

if(len1!=len){ 

c0=index64[strIn.charAt(i)]; 

c1=index64[strIn.charAt(i+1)]; 

c2=strIn.charAt(i+2); 

b0=(c0<<2)|(c1>>4); 

result.push(b0&0xff); 

if(c2!='='){ 

c2=index64[c2]; 

b1=(c1<<4)|(c2>>2); 

result.push(b1&0xff); 

} 

} 

return result; 

} 

//用于GIF的LZW解码函数 

//arrBytes为源数据,nBits为初始编码位数 

//成功返回数组,每个元素包括一个颜色索引 

//失败返回null 

function decodeLzw(arrBytes,nBits){ 

var cc=1<<(nBits-1); 

var eoi=cc+1; 

var table=[],mask=[],result=[]; 

for(var i=0;i<cc;i++) 

table[i]=(i>>8&0xf).toString(16) 

+(i>>4&0xf).toString(16)+(i&0xf).toString(16); 

for(i=2,mask[1]=1;i<13;i++) 

mask[i]=mask[i-1]<<1|1; 

var bc=nBits; 

var pos=0,temp=0,tleft=0,code=0,old=0; 

while(true){ 

while(tleft<bc){ 

temp=temp|(arrBytes[pos++]<<tleft); 

tleft+=8; 

} 

code=temp&mask[bc]; 

tleft-=bc; 

temp>>=bc; 

if(code==eoi) 

break; 

if(code==cc){ 

table.length=cc+2; 

bc=nBits; 

old=code; 

continue; 

} 

var t=""; 

if(code<table.length){ 

t=table[code]; 

if(old!=cc) 

table.push(table[old]+t.slice(0,3)); 

} 

else if(old<table.length){ 

t=table[old]+table[old].slice(0,3); 

table.push(t); 

} 

else{ 

alert("错误:图像数据无效"); 

return null; 

} 

old=code; 

for(var i=0;i<t.length;i+=3) 

result.push(parseInt(t.substr(i,3),16)) 

if(table.length==1<<bc&&bc<12) 

bc++; 

} 

return result; 

} 

//根据字节数组data布局,以最少的div完成绘图 

function defLayout(data,palette,width,height,image,block,zoom){ 

var map=new Array(height); 

for(var i=0;i<height;i++){ 

map[i]=new Array(width); 

for(var j=0;j<width;j++) 

map[i][j]=data[i*width+j]; 

} 

var i,j,i1,i2,j1,j2,c; 

for(i=0;i<height;i++) 

for(j=0;j<width;){ 

if(map[i][j]==0x100){ 

j++; 

continue; 

} 

c=map[i][j]; 

for(i1=i+1;i1<height&&map[i1][j]==c;i1++); 

for(j1=j+1;j1<width;j1++){ 

for(i2=i;i2<i1&&map[i2][j1]==c;i2++); 

if(i2<i1) 

break; 

} 

for(i2=i;i2<i1;i2++) 

for(j2=j;j2<j1;j2++) 

map[i2][j2]=0x100; 

var x=block.cloneNode(true); 

x.style.left=j*zoom; 

x.style.top=i*zoom; 

x.style.width=(j1-j)*zoom; 

x.style.height=(i1-i)*zoom; 

x.style.backgroundColor=palette[c]; 

image.appendChild(x); 

j=j1; 

} 

} 

</SCRIPT> 

<script> 

function main(){ 

var t=new Date().getTime(); 

var xmldom=document.getElementById("imgData"); 

var gif=getGif("R0lGODlhDwAPAKECAAAAzMzM/////wAAACwAAAAADwAPAAACIISPeQHsrZ5ModrLlN48CXF8m2iQ3YmmKqVlRtW4MLwWACH+H09wdGltaXplZCBieSBVbGVhZCBTbWFydFNhdmVyIQAAOw=="); 

var info=document.getElementById("info"); 

info.innerHTML=gif.showInfo("<br>"); 

t=new Date().getTime(); 

gif.frames[0].draw(document.getElementById("canvas"),1); 

info.innerHTML+="<br>绘图耗时"+(new Date().getTime()-t)+"ms"; 

} 

</SCRIPT> 

<body onload="main()"> 

<div id="canvas"></div> 

<hr> 

<div id="info">页面载入中,请稍候...</div> 

</body> 

</html>
Javascript 相关文章推荐
safari,opera嵌入iframe页面cookie读取问题解决方法
Jun 23 Javascript
Jquery 动态生成表格示例代码
Dec 24 Javascript
页面加载完毕后滚动条自动滚动一定位置
Feb 20 Javascript
怎么判断js脚本加载完成
Feb 28 Javascript
2种jQuery 实现刮刮卡效果
Feb 01 Javascript
JavaScript实现列表分页功能特效
May 15 Javascript
jquery实现文本框的禁用和启用
Dec 07 Javascript
67 个节约开发时间的前端开发者的工具、库和资源
Sep 12 Javascript
JS通过位运算实现权限加解密
Aug 14 Javascript
node学习笔记之读写文件与开启第一个web服务器操作示例
May 29 Javascript
JavaScript获取某一天所在的星期
Sep 05 Javascript
vue 中使用print.js导出pdf操作
Nov 13 Javascript
javascript文件中引用依赖的js文件的方法
Mar 17 #Javascript
jquery解析JSON数据示例代码
Mar 17 #Javascript
javascript事件函数中获得事件源的两种不错方法
Mar 17 #Javascript
javascript内置对象arguments详解
Mar 16 #Javascript
javascript跨浏览器的属性判断方法
Mar 16 #Javascript
JS高级调试技巧:捕获和分析 JavaScript Error详解
Mar 16 #Javascript
Jquery 在页面加载后执行的几种方式
Mar 14 #Javascript
You might like
全国FM电台频率大全 - 31 新疆维吾尔族自治区
2020/03/11 无线电
php 获取可变函数参数的函数
2009/08/26 PHP
php 指定范围内多个随机数代码实例
2016/07/18 PHP
php版微信js-sdk支付接口类用法示例
2016/10/12 PHP
PHP读取XML文件的方法实例总结【DOMDocument及simplexml方法】
2019/09/10 PHP
JavaScript中的Document文档对象
2008/01/16 Javascript
javascript 读取XML数据,在页面中展现、编辑、保存的实现
2009/10/27 Javascript
JavaScript 操作键盘的Enter事件(键盘任何事件),兼容多浏览器
2010/10/11 Javascript
巧用js提交表单轻松解决一个页面有多个提交按钮
2013/11/17 Javascript
让jQuery与其他JavaScript库并存避免冲突的方法
2013/12/23 Javascript
Document.body.scrollTop的值总为零的快速解决办法
2016/06/09 Javascript
jQuery实现6位数字密码输入框
2016/12/29 Javascript
js通过指定下标或指定元素进行删除数组的实例
2017/01/12 Javascript
详解Angular.js数据绑定时自动转义html标签及内容
2017/03/30 Javascript
深入浅析javascript继承体系
2017/10/23 Javascript
Angularjs Promise实例详解
2018/03/15 Javascript
vuejs实现ready函数加载完之后执行某个函数的方法
2018/08/31 Javascript
200行HTML+JavaScript实现年会抽奖程序
2019/01/22 Javascript
基于Vue实现微前端的示例代码
2020/04/24 Javascript
Python原始字符串(raw strings)用法实例
2014/10/13 Python
详解Python 序列化Serialize 和 反序列化Deserialize
2017/08/20 Python
Python使用numpy产生正态分布随机数的向量或矩阵操作示例
2018/08/22 Python
Python实现批量修改图片格式和大小的方法【opencv库与PIL库】
2018/12/03 Python
Python编程快速上手——正则表达式查找功能案例分析
2020/02/28 Python
浅谈Python中os模块及shutil模块的常规操作
2020/04/03 Python
python入门:argparse浅析 nargs='+'作用
2020/07/12 Python
Python3利用openpyxl读写Excel文件的方法实例
2021/02/03 Python
美国电视购物:QVC
2017/02/06 全球购物
在网上学习全世界最好的课程:Coursera
2017/11/07 全球购物
学院领导推荐信
2013/10/30 职场文书
小学运动会口号
2014/06/07 职场文书
颂军魂爱军营演讲稿
2014/09/13 职场文书
医院护士见习期自我鉴定
2014/09/15 职场文书
cf战队宣传语
2015/07/13 职场文书
2016年“我们的节日·重阳节”主题活动总结
2016/04/01 职场文书
mysql升级到5.7时,wordpress导数据报错1067的问题
2021/05/27 MySQL