1.为什么要用到BASE64编码的图片信息?
??? Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一。Base64 主要不是加密,它主要的用途是把一些二进制数转成普通字符用于网络传输。由于一些二进制字符在传输协议中属于控制字符,不能直接传送需要转换一下。最常见的用途是作为电子邮件或WebService附件的传输编码.?
2.base64编码定义?
目前的internet e-mail标准--简单邮件传递协议(smtp)在rfc821中规定了两条重要但不难实现的限制:?
??????? 1)邮件的内容必须全部为7-比特的美国ascii码。?
??????? 2)每一行的长度不能超过1000的字符。?
??? 因此为了通过smtp用e-mail进行传送,内存的序列化对象必须转化为和以上相容的格式。?
??? rfc1521提供了一个可行的方案。它定义了邮件的内容部分,使之能包涵多种形式的数据。这种标准就是目前众所周知的mime。?
按照rfc1521编码过程为:输入是24个比特,输出是4个字节。24个比特输入组从左至右 由3个8比特的输入组形成。这24个比特被看成4个连续的6比特组,而每个6比特输入组被翻译为base64码表中的一个数字。依次反复不断进行,直到全部输入数据转换完成。?
??? 如果最后剩下两个输入数据,在编码结果后加1个“=”;如果最后剩下一个输入数据,编码结果后加2个“=”;如果没有剩下任何数据,就什么都不要加,这样才可以保证资料还原的正确性。?
??? 完整的base64定义可见 RFC1421和 RFC2045。编码后的数据比原始数据略长,为原来的4/3。在电子邮件中,根据RFC822规定,每76个字符,还需要加上一个回车换行。可以估算编码后数据长度大约为原长的135.1%。?
4.显示被存储为Base64编码字符串的图片的例子?
1)使用data: URI直接在网页中嵌入.?
data: URI定义于IETF标准的RFC 2397?
data: URI的基本使用格式如下:?
data:[<MIME-type>][;base64|charset=some_charset],<data>?
mime-type是嵌入数据的mime类型,比如png图片就是image/png。?
如果后面跟base64,说明后面的data是采用base64方式进行编码的?
?
? 这种方式,Firfox、Opera、Safari和Konqueror这些浏览器都已经支持,但是IE直到7.0版本都还没有支持.所以,比较好的做法是在服务器端将base64编码的字符串转换成byte流.这里,我提供了java的实现方法.?
?
?
图片转换为base64格式的图片和样式的路径:
http://ippa.se/base64-image-encoder/
?
?
?
<!DOCTYPE html > <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>电子签名的使用</title> <style type="text/css"> #canvas { border: 1px solid #ccc; } </style> </head> <body> <div id="canvasDiv"></div> <button id="btn_clear">Clear</button> <button id="btn_submit">Submit</button> <form action="./Base64ToImages" method="post"><input type="hidden" name="imageData" id="imageData" /></form> <img id="tempImage" src="" style="display: none;" alt="临时图片文件" /> <script language="javascript"> var canvasDiv = document.getElementById('canvasDiv'); var canvas = document.createElement('canvas'); var canvasWidth = 600, canvasHeight = 400; var point = {}; point.notFirst = false; canvas.setAttribute('width', canvasWidth); canvas.setAttribute('height', canvasHeight); canvas.setAttribute('id', 'canvas'); canvasDiv.appendChild(canvas); if (typeof G_vmlCanvasManager != 'undefined') { canvas = G_vmlCanvasManager.initElement(canvas); } var context = canvas.getContext("2d"); canvas.addEventListener("mousedown", function(e) { var mouseX = e.pageX - this.offsetLeft; var mouseY = e.pageY - this.offsetTop; paint = true; addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop); redraw(); }); canvas.addEventListener("mousemove", function(e) { if (paint) { addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop, true); redraw(); } }); canvas.addEventListener("mouseup", function(e) { paint = false; }); canvas.addEventListener("mouseleave", function(e) { paint = false; }); var clickX = new Array(); var clickY = new Array(); var clickDrag = new Array(); var paint; function addClick(x, y, dragging) { clickX.push(x); clickY.push(y); clickDrag.push(dragging); } function redraw() { //canvas.width = canvas.width; // Clears the canvas context.strokeStyle = "#df4b26"; context.lineJoin = "round"; context.lineWidth = 5; while (clickX.length > 0) { point.bx = point.x; point.by = point.y; point.x = clickX.pop(); point.y = clickY.pop(); point.drag = clickDrag.pop(); context.beginPath(); if (point.drag && point.notFirst) { context.moveTo(point.bx, point.by); } else { point.notFirst = true; context.moveTo(point.x - 1, point.y); } context.lineTo(point.x, point.y); context.closePath(); context.stroke(); } /* for(var i=0; i < clickX.length; i++) { context.beginPath(); if(clickDrag[i] && i){ context.moveTo(clickX[i-1], clickY[i-1]); }else{ context.moveTo(clickX[i]-1, clickY[i]); } context.lineTo(clickX[i], clickY[i]); context.closePath(); context.stroke(); } */ } var clear = document.getElementById("btn_clear"); var submit = document.getElementById("btn_submit"); clear.addEventListener("click", function() { canvas.width = canvas.width; }); submit.addEventListener("click", function() { //获取当前页面的信息,在当前页面的img下展示 var image = document.getElementById("tempImage"); image.src = canvas.toDataURL("image/png"); document.getElementById("imageData").value = canvas .toDataURL("image/png"); image.style = "display:block;"; //获取canvas的数据格式如下 alert(canvas.toDataURL("image/png")); //提交表单数据信息 document.forms[0].submit(); }); </script> </body> </html>
?
?
Servlert代码如下:
?
package com.easyway.html5.canvas; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.Date; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import sun.misc.BASE64Decoder; /** * * Servlet implementation class Base64ToImages */ public class Base64ToImages extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public Base64ToImages() { super(); } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse * response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request,response); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse * response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { base64toImage(request); } /** * 处理base64转化image的方法 * @param request */ public void base64toImage(HttpServletRequest request) { try { String base64data = request.getParameter("imageData"); String imageData=base64data.split(",")[1]; BASE64Decoder decoder = new BASE64Decoder(); byte[] imgBytes = decoder.decodeBuffer(imageData); for (int i = 0; i < imgBytes.length; ++i) { if (imgBytes[i] < 0) {// 调整异常数据 imgBytes[i] += 256; } } //保存特定的目录下面 String imagepath =getServletContext().getRealPath("/images"); System.out.println("imagepath="+imagepath); File dir=new File(imagepath); if(!dir.exists()){ dir.mkdirs(); } String filename=new Date().getTime()+".png"; File decFile = new File(imagepath+File.separator+filename); String dd=decFile.getAbsolutePath(); if(decFile.exists()){ decFile.delete(); } decFile.createNewFile(); FileOutputStream ops = new FileOutputStream(decFile); ops.write(imgBytes, 0, imgBytes.length); ops.flush(); ops.close(); } catch (IOException e) { e.printStackTrace(); } } }