利用HTML5中Canvas处理并存储图片
HTML5中增加的Canvas元素,配合JS灵活的语法,处理起图片变得异常简单,不需要在客户端用C/C++写一大堆代码,对于熟悉JS的程序员来说,只需要考虑处理图片的逻辑了。
canvas中如果想要处理图片就需要借助ImageData这个对象,就是将画布中某一区域中的图像以RGBA的方式保存下来,存成一个二维数组。
ctx.getImageData( x, y, w, h) //获取ImageData ctx.putImageData( x, y, w, h) //将ImageData绘在画布上
写了个简单的处理图像的类,可以翻转/灰化/去色/高亮/设单色值
/** * @author Norris Tong */ var PS = function( config ){ //$.extend( this, config ); return this; } PS.prototype = { //将图像灰化 gray : function( ctx, imageData ){ var w = imageData.width, h = imageData.height, ret = ctx.createImageData( w, h ); for (i=0; i<w; i++) { for (j=0; j<h; j++) { var index=(i*h+j) * 4; var red=imageData.data[index]; var green=imageData.data[index+1]; var blue=imageData.data[index+2]; var alpha=imageData.data[index+3]; var average=(red+green+blue)/3; ret.data[index]=average; ret.data[index+1]=average; ret.data[index+2]=average; ret.data[index+3]=alpha; } } return ret; }, // 生成ImageData createImageData : function( ctx, ori, from, w, h ){ var ret = ctx.createImageData( w, h ); var total = w * h * 4; from = from * w * 4; for (var i= 0 ; i< total; i++) { ret.data[ i ] = ori.data[ from + i ]; } return ret; }, //生成ImageData //对称图像反转 createImageDataTurn : function( ctx, ori, from, w, h ){ var ret = ctx.createImageData( w, h ); var total = w * h * 4; from = from * w * 4; for (var j=0; j<h; j++) { for (var i=0; i<w; i++) { var a = (j * w + i) * 4, b = from + a, c = (j * w + w- i) * 4; ret.data[ c++ ] = ori.data[ b++ ]; ret.data[ c++ ] = ori.data[ b++ ]; ret.data[ c++ ] = ori.data[ b++ ]; ret.data[ c++ ] = ori.data[ b++ ]; } } return ret; }, //将整个图片设置为某一颜色值 setColorR : function( ctx, imageData, n ){ var w = imageData.width, h = imageData.height, ret = ctx.createImageData( w, h ); var total = w * h * 4; for (var i=0; i<total; i +=4 ) { ret.data[i] = n; // imageData[ i ]; ret.data[i+1]= imageData.data[ i + 1 ]; ret.data[i+2]= imageData.data[ i + 2 ]; ret.data[ i+3]= imageData.data[ i + 3 ]; } return ret; }, //将整个图片设置为某一颜色值 setColorG : function( ctx, imageData, n ){ var w = imageData.width, h = imageData.height, ret = ctx.createImageData( w, h ); var total = w * h * 4; for (var i=0; i<total; i +=4 ) { var red=imageData.data[i], green=imageData.data[i+1], blue=imageData.data[i+2]; var a = (red + green + blue) / 3; ret.data[i] = a; ret.data[i+1]= a + n; ret.data[i+2]= a; ret.data[ i+3]= imageData.data[ i + 3 ]; } return ret; }, //将整个图片设置为某一颜色值 setColorB : function( ctx, imageData, n ){ var w = imageData.width, h = imageData.height, ret = ctx.createImageData( w, h ); var total = w * h * 4; for (var i=0; i<total; i +=4 ) { ret.data[i] = imageData.data[ i ]; ret.data[i+1]= imageData.data[ i + 1 ]; ret.data[i+2]= n; ret.data[ i+3]= imageData.data[ i + 3 ]; } return ret; }, //高亮整个图片 highlight : function( ctx, imageData, n ){ var w = imageData.width, h = imageData.height, ret = ctx.createImageData( w, h ); var total = w * h * 4; for (var i=0; i<total; i +=4 ) { ret.data[i] = imageData.data[ i ] + n; ret.data[i+1]= imageData.data[ i + 1 ] + n; ret.data[i+2]= imageData.data[ i + 2 ] + n; ret.data[ i+3]= imageData.data[ i + 3 ]; } return ret; }, //去色 紫色 247, 0, 255 removeColor : function( ctx, imageData, r, g, b ){ var w = imageData.width, h = imageData.height, ret = ctx.createImageData( w, h ); var total = w * h * 4; for (var i=0; i<total; i +=4 ) { var red=imageData.data[i], green=imageData.data[i+1], blue=imageData.data[i+2]; //相等则全透明 if ( r == red && green == g && blue == b ){ ret.data[ i+3]= 0; }else{ ret.data[i] = red; ret.data[i+1]= green; ret.data[i+2]= blue; ret.data[ i+3]= imageData.data[ i + 3 ]; } } return ret; } }; PS = new PS();
通过一系列操作,渲染好图像后,就需要借助如下的代码将画布中的图像保存成图片
//将图像输出为base64压缩的字符串 默认为image/png var data = canvas.toDataURL(); //删除字符串前的提示信息 "data:image/png;base64," var b64 = data.substring( 22 ); //POST到服务器上,生成图片 $.post( "save.aspx" , { data : b64, name : filename }, function(){ //OK });
save.aspx中的代码如下:
protected void Page_Load(object sender, EventArgs e) { if (Request["name"] != null) { string name = Request["name"]; String savePath = Server.MapPath("~/images/output/"); try { FileStream fs = File.Create(savePath + "/" + name); byte[] bytes = Convert.FromBase64String(Request["data"]); fs.Write(bytes, 0, bytes.Length); fs.Close(); } catch (Exception except) { } } }
PS: 由于沙箱的限制,想在浏览器端通过JS直接存为本地图片,似乎是不大可能,现在网上较为折中的方式为
window.location.href = "image/octet-stream" + data
但这种方式不能指定保存的文件名,在FF下默认是xxxxx.part
参照 : http://www.nihilogic.dk/labs/canvas2image/
转自:http://blog.csdn.net/northwind_x/article/details/5874680