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

8 提交 / 0个新回复
最新回复
HTML5中使用Canvas处理并存储图片

 
HTML5中增加的Canvas元素,配合JS灵活的语法,处理起图片变得异常简单,不需要在客户端用C/C++写一大堆代码,对于熟悉JS的程序员来说,只需要考虑处理图片的逻辑了。
canvas中如果想要处理图片就需要借助ImageData这个对象,就是将画布中某一区域中的图像以RGBA的方式保存下来,存成一个二维数组。

JavaScript Code复制内容到剪贴板

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

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

JavaScript Code复制内容到剪贴板

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

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

JavaScript Code复制内容到剪贴板

  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中的代码如下:

JavaScript Code复制内容到剪贴板

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

PS: 由于沙箱的限制,想在浏览器端通过JS直接存为本地图片,似乎是不大可能,现在网上较为折中的方式为
window.location.href = “image/octet-stream” + data
但这种方式不能指定保存的文件名,在FF下默认是xxxxx.part

标签: