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 相关文章推荐
js点击更换背景颜色或图片的实例代码
Jun 25 Javascript
javascript使用isNaN()函数判断变量是否为数字
Sep 21 Javascript
使用JavaScript获取电池状态的方法
May 03 Javascript
jQuery设置指定网页元素宽度和高度的方法
Mar 25 Javascript
jQuery Easyui Tabs扩展根据自定义属性打开页签
Aug 15 Javascript
jQuery简单实现MD5加密的方法
Mar 03 Javascript
使用yeoman构建angular应用的方法
Aug 14 Javascript
jqgrid实现简单的单行编辑功能
Sep 30 Javascript
JavaScript数组push方法使用注意事项
Oct 30 Javascript
angularJs中json数据转换与本地存储的实例
Oct 08 Javascript
Three.js实现3D机房效果
Dec 30 Javascript
vite+vue3.0+ts+element-plus快速搭建项目的实现
Jun 24 Vue.js
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
php与mysql建立连接并执行SQL语句的代码
2011/07/04 PHP
使用PHP获取当前url路径的函数以及服务器变量
2013/06/29 PHP
PHP四舍五入、取整、round函数使用示例
2015/02/06 PHP
php函数式编程简单示例
2019/08/08 PHP
最短的javascript:地址栏载入脚本代码
2011/10/13 Javascript
JavaScript Ajax Json实现上下级下拉框联动效果实例代码
2013/11/23 Javascript
jQuery中outerWidth()方法用法实例
2015/01/19 Javascript
Javascript简单改变表单元素背景的方法
2015/07/15 Javascript
纯jquery实现模仿淘宝购物车结算
2015/08/20 Javascript
JS实现超简洁网页title标题跑动闪烁提示效果代码
2015/10/23 Javascript
JavaScript学习笔记之数组求和方法
2016/03/23 Javascript
jQuery实现页面顶部下拉广告
2016/12/30 Javascript
jQuery插件zTree实现删除树子节点的方法示例
2017/03/08 Javascript
vue.js引入外部CSS样式和外部JS文件的方法
2019/01/06 Javascript
通过实例了解JS 连续赋值
2019/09/24 Javascript
使用JS来动态操作css的几种方法
2019/12/18 Javascript
python处理圆角图片、圆形图片的例子
2014/04/25 Python
Python和Perl绘制中国北京跑步地图的方法
2016/03/03 Python
Python使用迭代器打印螺旋矩阵的思路及代码示例
2016/07/02 Python
Python实现螺旋矩阵的填充算法示例
2017/12/28 Python
Python和Java进行DES加密和解密的实例
2018/01/09 Python
Python基础学习之时间转换函数用法详解
2019/06/18 Python
python读写csv文件实例代码
2019/07/05 Python
利用python中集合的唯一性实现去重
2020/02/11 Python
如何在scrapy中集成selenium爬取网页的方法
2020/11/18 Python
HTML5 与 XHTML2
2008/10/17 HTML / CSS
Canvas globalCompositeOperation
2018/12/18 HTML / CSS
印度网上购物首选目的地:Flipkart
2016/08/01 全球购物
挪威手表购物网站:Klokker
2016/09/19 全球购物
佐卡伊官网:中国知名珠宝品牌
2017/02/05 全球购物
英国领先的新鲜松露和最好的松露产品供应商:TruffleHunter
2019/08/26 全球购物
单位消防安全制度
2014/01/12 职场文书
安全标语大全
2014/06/10 职场文书
干部外出学习心得体会
2016/01/18 职场文书
springboot临时文件存储目录配置方式
2021/07/01 Java/Android
python自动化测试通过日志3分钟定位bug
2021/11/20 Python