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

论坛 期权论坛 脚本     
匿名技术用户   2021-1-5 04:54   59   0
HTML5中增加的Canvas元素,配合JS灵活的语法,处理起图片变得异常简单,不需要在客户端用C/C++写一大堆代码,对于熟悉JS的程序员来说,只需要考虑处理图片的逻辑了。

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

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

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

  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();

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

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

  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

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

来处:
http://blog.csdn.net/northwind_x/archive/2010/09/10/5874680.aspx


分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP