`

利用HTML5中Canvas处理并存储图片

阅读更多

      HTML5中增加的Canvas元素,配合JS灵活的语法,处理起图片变得异常简单,不需要在客户端用C/C++写一大堆代码,对于熟悉JS的程序员来说,只需要考虑处理图片的逻辑了。

 


 

      canvas中如果想要处理图片就需要借助ImageData这个对象,就是将画布中某一区域中的图像以RGBA的方式保存下来,存成一个二维数组。

    

[javascript] view plaincopy
  1. ctx.getImageData( x, y, w, h)      //获取ImageData  
  2. ctx.putImageData( x, y, w, h)     //将ImageData绘在画布上  

   

     写了个简单的处理图像的类,可以翻转/灰化/去色/高亮/设单色值

    

[javascript] view plaincopy
  1. /** 
  2.  * @author Norris Tong 
  3.  */  
  4.   
  5. var PS = function( config ){  
  6.     //$.extend( this, config );  
  7.     return this;  
  8. }  
  9.   
  10. PS.prototype = {  
  11.       
  12.     //将图像灰化  
  13.     gray        : function( ctx, imageData ){  
  14.         var w = imageData.width,  
  15.                 h = imageData.height,  
  16.                 ret = ctx.createImageData( w, h );  
  17.           
  18.         for (i=0; i<w; i++)  
  19.         {  
  20.             for (j=0; j<h; j++)  
  21.             {  
  22.                 var index=(i*h+j) * 4;  
  23.               
  24.                 var red=imageData.data[index];  
  25.                 var green=imageData.data[index+1];  
  26.                 var blue=imageData.data[index+2];  
  27.                 var alpha=imageData.data[index+3];  
  28.               
  29.                 var average=(red+green+blue)/3;  
  30.               
  31.                 ret.data[index]=average;  
  32.                 ret.data[index+1]=average;  
  33.                 ret.data[index+2]=average;  
  34.                 ret.data[index+3]=alpha;  
  35.               }  
  36.         }  
  37.           
  38.         return ret;  
  39.     },  
  40.       
  41.     // 生成ImageData  
  42.     createImageData : function( ctx, ori, from, w, h ){  
  43.             var ret = ctx.createImageData( w, h );  
  44.             var total = w * h * 4;  
  45.             from = from * w * 4;  
  46.             for (var i= 0 ; i< total; i++) {  
  47.                 ret.data[ i ] = ori.data[ from + i ];  
  48.             }  
  49.               
  50.             return ret;  
  51.     },  
  52.       
  53.     //生成ImageData  
  54.     //对称图像反转  
  55.      createImageDataTurn    : function( ctx, ori, from, w, h ){  
  56.             var ret = ctx.createImageData( w, h );  
  57.             var total = w * h * 4;  
  58.             from = from * w * 4;  
  59.             for (var j=0; j<h; j++) {  
  60.                 for (var i=0; i<w; i++) {  
  61.                     var  a =  (j * w + i) * 4,  
  62.                             b = from + a,  
  63.                             c =  (j * w + w- i) * 4;  
  64.                               
  65.                     ret.data[ c++ ] = ori.data[ b++ ];  
  66.                     ret.data[ c++ ] = ori.data[ b++ ];  
  67.                     ret.data[ c++ ] = ori.data[ b++ ];  
  68.                     ret.data[ c++ ] = ori.data[ b++ ];  
  69.                 }  
  70.             }  
  71.               
  72.             return ret;  
  73.     },  
  74.       
  75.     //将整个图片设置为某一颜色值  
  76.      setColorR  : function( ctx, imageData, n ){  
  77.         var w = imageData.width,  
  78.                 h = imageData.height,  
  79.                 ret = ctx.createImageData( w, h );  
  80.           
  81.         var total = w * h * 4;  
  82.           
  83.         for (var i=0; i<total; i +=4 ) {  
  84.               
  85.             ret.data[i]  = n; // imageData[ i ];  
  86.             ret.data[i+1]= imageData.data[ i + 1 ];  
  87.             ret.data[i+2]= imageData.data[ i + 2 ];  
  88.             ret.data[ i+3]= imageData.data[ i + 3 ];  
  89.         }     
  90.           
  91.         return ret;  
  92.     },  
  93.       
  94.     //将整个图片设置为某一颜色值  
  95.      setColorG  : function( ctx, imageData, n ){  
  96.         var w = imageData.width,  
  97.                 h = imageData.height,  
  98.                 ret = ctx.createImageData( w, h );  
  99.           
  100.         var total = w * h * 4;  
  101.           
  102.         for (var i=0; i<total; i +=4 ) {  
  103.             var red=imageData.data[i],  
  104.                 green=imageData.data[i+1],  
  105.                 blue=imageData.data[i+2];  
  106.               
  107.             var a = (red + green + blue) / 3;  
  108.                   
  109.             ret.data[i]  = a;  
  110.             ret.data[i+1]= a + n;  
  111.             ret.data[i+2]= a;  
  112.             ret.data[ i+3]= imageData.data[ i + 3 ];  
  113.         }     
  114.           
  115.         return ret;  
  116.     },  
  117.       
  118.     //将整个图片设置为某一颜色值  
  119.      setColorB  : function( ctx, imageData, n ){  
  120.         var w = imageData.width,  
  121.                 h = imageData.height,  
  122.                 ret = ctx.createImageData( w, h );  
  123.           
  124.         var total = w * h * 4;  
  125.           
  126.         for (var i=0; i<total; i +=4 ) {  
  127.               
  128.             ret.data[i]  = imageData.data[ i ];  
  129.             ret.data[i+1]= imageData.data[ i + 1 ];  
  130.             ret.data[i+2]= n;  
  131.             ret.data[ i+3]= imageData.data[ i + 3 ];  
  132.         }     
  133.           
  134.         return ret;  
  135.     },  
  136.       
  137.     //高亮整个图片  
  138.      highlight  : function( ctx, imageData, n ){  
  139.         var w = imageData.width,  
  140.                 h = imageData.height,  
  141.                 ret = ctx.createImageData( w, h );  
  142.           
  143.         var total = w * h * 4;  
  144.           
  145.         for (var i=0; i<total; i +=4 ) {  
  146.               
  147.             ret.data[i]  = imageData.data[ i ] + n;  
  148.             ret.data[i+1]= imageData.data[ i + 1 ] + n;  
  149.             ret.data[i+2]= imageData.data[ i + 2 ] + n;  
  150.             ret.data[ i+3]= imageData.data[ i + 3 ];  
  151.         }     
  152.           
  153.         return ret;  
  154.     },  
  155.       
  156.     //去色   紫色 247, 0, 255  
  157.      removeColor    : function( ctx, imageData, r, g, b ){  
  158.         var w = imageData.width,  
  159.                 h = imageData.height,  
  160.                 ret = ctx.createImageData( w, h );  
  161.           
  162.         var total = w * h * 4;  
  163.           
  164.         for (var i=0; i<total; i +=4 ) {  
  165.             var red=imageData.data[i],  
  166.                 green=imageData.data[i+1],  
  167.                 blue=imageData.data[i+2];  
  168.               
  169.             //相等则全透明      
  170.             if ( r == red && green == g && blue == b ){  
  171.                 ret.data[ i+3]= 0;  
  172.             }else{  
  173.                 ret.data[i]  = red;  
  174.                 ret.data[i+1]= green;  
  175.                 ret.data[i+2]= blue;  
  176.                 ret.data[ i+3]= imageData.data[ i + 3 ];  
  177.             }  
  178.         }     
  179.           
  180.         return ret;  
  181.     }                     
  182.       
  183. };  
  184.   
  185. PS = new PS();  

 

     通过一系列操作,渲染好图像后,就需要借助如下的代码将画布中的图像保存成图片

    

[c-sharp] view plaincopy
  1. //将图像输出为base64压缩的字符串  默认为image/png  
  2. var data = canvas.toDataURL();                      
  3. //删除字符串前的提示信息 "data:image/png;base64,"  
  4. var b64 = data.substring( 22 );  
  5. //POST到服务器上,生成图片                      
  6. $.post( "save.aspx" , { data : b64, name : filename }, function(){  
  7.     //OK  
  8. });  

    

    save.aspx中的代码如下:

   

[c-sharp] view plaincopy
  1. protected void Page_Load(object sender, EventArgs e)  
  2. {  
  3.     if (Request["name"] != null)  
  4.     {  
  5.         string name = Request["name"];  
  6.   
  7.         String savePath = Server.MapPath("~/images/output/");  
  8.   
  9.         try  
  10.         {  
  11.             FileStream fs = File.Create(savePath + "/" + name);  
  12.   
  13.             byte[] bytes = Convert.FromBase64String(Request["data"]);  
  14.   
  15.             fs.Write(bytes, 0, bytes.Length);  
  16.             fs.Close();  
  17.         }  
  18.         catch (Exception except)  
  19.         {  
  20.         }  
  21.   
  22.     }  
  23. }  

 

   PS: 由于沙箱的限制,想在浏览器端通过JS直接存为本地图片,似乎是不大可能,现在网上较为折中的方式为

   window.location.href = "image/octet-stream" + data

   但这种方式不能指定保存的文件名,在FF下默认是xxxxx.part

   参照 : http://www.nihilogic.dk/labs/canvas2image/

分享到:
评论

相关推荐

    工程硕士学位论文 基于Android+HTML5的移动Web项目高效开发探究

    目前市场业务中在产品以及其他项目的认证和检测方面存在诸多不便,用户需要实地考察并频繁与检测单位沟通,填写繁琐的纸质检测报告、当面送递样品,对于检测环节中存在的问题难以及时交互并处理。市场上相应的检测...

    delphi 开发经验技巧宝典源码

    第5章 字符与字符串处理技术 99 5.1 ASCII码与编码转换 100 0150 如何获得汉字的区位码 100 0151 通过区位码获取汉字 100 0152 根据ASCII码获得字母 101 0153 获得字母的ASCII码 101 5.2 字符中的转换...

    Delphi7编程100例

    利用书签处理DBGrid中的多个记录 将ComboBox中的内容直接拖放到DBGrid里 如何在DBGrid里放置图标 DBGrid控件精彩组合 DBChart图表控件的使用 在StringGrid组件中显示查询结果 使用流对象(Tstream)...

    Delphi编程100例

    利用书签处理DBGrid中的多个记录 将ComboBox中的内容直接拖放到DBGrid里 如何在DBGrid里放置图标 DBGrid控件精彩组合 DBChart图表控件的使用 在StringGrid组件中显示查询结果 使用流对象(Tstream)实现数据表中...

    JavaScript权威指南(第6版)中文文字版

    7.9 ecmascript 5中的数组方法 156 7.10 数组类型 160 7.11 类数组对象 161 7.12 作为数组的字符串 163 第8章 函数 165 8.1 函数定义 166 8.2 函数调用 168 8.3 函数的实参和形参 173 8.4 作为值的函数 178 8.5 作为...

    《Delphi7编程100例》代码

    ToolBar工具栏控件的使用动态建立主菜单选项窗口界面的动态分隔条动态...Canvas生成渐变色窗口背景WINAPM风格磁化窗口软件封面的图片显示制作实现图片的任意角度旋转奇妙的拼图游戏使用PaintBox控件制作画图程序使用...

    delphi 开发经验技巧宝典源码06

    第5章 字符与字符串处理技术 99 5.1 ASCII码与编码转换 100 0150 如何获得汉字的区位码 100 0151 通过区位码获取汉字 100 0152 根据ASCII码获得字母 101 0153 获得字母的ASCII码 101 5.2 字符中的转换...

    JavaScript权威指南(第6版) 中文版

    7.9 ecmascript 5中的数组方法 156 7.10 数组类型 160 7.11 类数组对象 161 7.12 作为数组的字符串 163 第8章 函数 165 8.1 函数定义 166 8.2 函数调用 168 8.3 函数的实参和形参 173 8.4 作为值的函数 178 8.5 作为...

    JavaScript权威指南(第6版)

    7.9 ecmascript 5中的数组方法 156 7.10 数组类型 160 7.11 类数组对象 161 7.12 作为数组的字符串 163 第8章 函数 165 8.1 函数定义 166 8.2 函数调用 168 8.3 函数的实参和形参 173 8.4 作为值的函数 178 8.5 作为...

    JavaScript权威指南(第6版)(中文版)

    7.9 ecmascript 5中的数组方法 156 7.10 数组类型 160 7.11 类数组对象 161 7.12 作为数组的字符串 163 第8章 函数 165 8.1 函数定义 166 8.2 函数调用 168 8.3 函数的实参和形参 173 8.4 作为值的函数 178 8.5 作为...

    Delphi7 编程 100 实例

    ToolBar工具栏控件的使用 动态建立主菜单选项 窗口界面的动态分隔...Canvas生成渐变色窗口背景 WINAPM风格磁化窗口 软件封面的图片显示制作 实现图片的任意角度旋转 奇妙的拼图游戏 使用PaintBox...

    delphi7编程百例

    ToolBar工具栏控件的使用 动态建立主菜单选项 窗口界面的动态...Canvas生成渐变色窗口背景 WINAPM风格磁化窗口 软件封面的图片显示制作 实现图片的任意角度旋转 奇妙的拼图游戏 使用...

    vue-lottery:抽奖以及截屏保存图片至本地

    简介基于vue.js抽奖项目,截屏保存多次抽奖图片至本地,附带背景音乐技术栈:vue + vuex + vue-router + axios +模拟+ elementUI + html2canvas + nprogress +更少+ ECMAScript6本项目目前处于持续更新阶段,欢迎...

    Google Android SDK开发范例大全(PDF高清完整版3)(4-3)

    10.2 GPS轨迹记录器——利用LocationListener在地图上画图并换算距离 10.3 女性贴身看护——AlarmManager.DatePicker.TimePicker 10.4 手机QRCode二维条形码生成器——Canvas与SurfaceHolder绘图 10.5 AndroidQRCode...

    Google Android SDK开发范例大全(PDF完整版4)(4-4)

    10.2 GPS轨迹记录器——利用LocationListener在地图上画图并换算距离 10.3 女性贴身看护——AlarmManager.DatePicker.TimePicker 10.4 手机QRCode二维条形码生成器——Canvas与SurfaceHolder绘图 10.5 AndroidQRCode...

    Google Android SDK开发范例大全(PDF高清完整版1)(4-1)

    10.2 GPS轨迹记录器——利用LocationListener在地图上画图并换算距离 10.3 女性贴身看护——AlarmManager.DatePicker.TimePicker 10.4 手机QRCode二维条形码生成器——Canvas与SurfaceHolder绘图 10.5 AndroidQRCode...

    Google Android SDK开发范例大全(完整版附部分源码).pdf

    10.2 GPS轨迹记录器——利用LocationListener在地图上画图并换算距离 10.3 女性贴身看护——AlarmManager.DatePicker.TimePicker 10.4 手机QRCode二维条形码生成器——Canvas与SurfaceHolder绘图 10.5 ...

    Google Android SDK开发范例大全的目录

    10.2 GPS轨迹记录器——利用LocationListener在地图上画图并换算距离 10.3 女性贴身看护——AlarmManager.DatePicker.TimePicker 10.4 手机QRCode二维条形码生成器——Canvas与SurfaceHolder绘图 10.5 AndroidQRCode...

Global site tag (gtag.js) - Google Analytics