HTML5中增加的Canvas元素,配合JS灵活的语法,处理起图片变得异常简单,不需要在客户端用C/C 写一大堆代码,对于熟悉JS的程序员来说,只需要考虑处理图片的逻辑了。
canvas中如果想要处理图片就需要借助ImageData这个对象,就是将画布中某一区域中的图像以RGBA的方式保存下来,存成一个二维数组。
JavaScript
ctx.getImageData( x, y, w, h) //获取ImageData
ctx.putImageData( x, y, w, h) //将ImageData绘在画布上
写了个简单的处理图像的类,可以翻转/灰化/去色/高亮/设单色值
JavaScript
/**
* @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();
通过一系列操作,渲染好图像后,就需要借助如下的代码将画布中的图像保存成图片
JavaScript
//将图像输出为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中的代码如下:
JavaScript
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