HTML5 Canvas图片马赛克模糊动画

布满荆棘的人生 2022-07-30 13:12 371阅读 0赞

经常可以在网上或者电视上看到被马赛克模糊的图片或者视频,今天我们要利用HTML5 Canvas技术来实现图片的马赛克模糊效果。在演示中我们可以拖动滑竿来设置马赛克模糊的程度,你可以在不同的值下观察图片被马赛克后的效果。HTML5的确非常强大。

html5-canvas-image-mosaics

HTML代码如下

  1. <div class="thumb">
  2. <img src="img/1.jpg" id="dolly1" />
  3. <img src="img/2.jpg" id="dolly2" />
  4. <img src="img/3.jpg" id="dolly3" />
  5. </div>

定义了一个滑竿和3张待模糊的图片。

JavaScript代码如下

  1. /*!
  2. * Close Pixelate v2.0.00 beta
  3. * http://desandro.com/resources/close-pixelate/
  4. *
  5. * Developed by
  6. * - David DeSandro http://desandro.com
  7. * - John Schulz http://twitter.com/jfsiii
  8. *
  9. * Licensed under MIT license
  10. */
  11. /*jshint asi: true, browser: true, eqeqeq: true, forin: false, immed: false, newcap: true, noempty: true, strict: true, undef: true */
  12. ( function( window, undefined ) {
  13. //
  14. 'use strict';
  15. // util vars
  16. var TWO_PI = Math.PI * 2
  17. var QUARTER_PI = Math.PI * 0.25
  18. // utility functions
  19. function isArray( obj ) {
  20. return Object.prototype.toString.call( obj ) === "[object Array]"
  21. }
  22. function isObject( obj ) {
  23. return Object.prototype.toString.call( obj ) === "[object Object]"
  24. }
  25. var console = window.console
  26. // check for canvas support
  27. var canvas = document.createElement('canvas')
  28. var isCanvasSupported = canvas.getContext && canvas.getContext('2d')
  29. // don't proceed if canvas is no supported
  30. if ( !isCanvasSupported ) {
  31. return
  32. }
  33. function ClosePixelation( img, options ) {
  34. this.img = img
  35. // creat canvas
  36. var canvas = this.canvas = document.createElement('canvas')
  37. this.ctx = canvas.getContext('2d')
  38. // copy attributes from img to canvas
  39. canvas.className = img.className
  40. canvas.id = img.id
  41. this.render( options )
  42. // replace image with canvas
  43. img.parentNode.replaceChild( canvas, img )
  44. }
  45. ClosePixelation.prototype.render = function( options ) {
  46. this.options = options
  47. // set size
  48. var w = this.width = this.canvas.width = this.img.width
  49. var h = this.height = this.canvas.height = this.img.height
  50. // draw image on canvas
  51. this.ctx.drawImage( this.img, 0, 0 )
  52. // get imageData
  53. try {
  54. this.imgData = this.ctx.getImageData( 0, 0, w, h ).data
  55. } catch ( error ) {
  56. if ( console ) {
  57. console.error( error )
  58. }
  59. return
  60. }
  61. this.ctx.clearRect( 0, 0, w, h )
  62. for ( var i=0, len = options.length; i < len; i++ ) {
  63. this.renderClosePixels( options[i] )
  64. }
  65. }
  66. ClosePixelation.prototype.renderClosePixels = function( opts ) {
  67. var w = this.width
  68. var h = this.height
  69. var ctx = this.ctx
  70. var imgData = this.imgData
  71. // option defaults
  72. var res = opts.resolution || 16
  73. var size = opts.size || res
  74. var alpha = opts.alpha || 1
  75. var offset = opts.offset || 0
  76. var offsetX = 0
  77. var offsetY = 0
  78. var cols = w / res + 1
  79. var rows = h / res + 1
  80. var halfSize = size / 2
  81. var diamondSize = size / Math.SQRT2
  82. var halfDiamondSize = diamondSize / 2
  83. if ( isObject( offset ) ){
  84. offsetX = offset.x || 0
  85. offsetY = offset.y || 0
  86. } else if ( isArray( offset) ){
  87. offsetX = offset[0] || 0
  88. offsetY = offset[1] || 0
  89. } else {
  90. offsetX = offsetY = offset
  91. }
  92. var row, col, x, y, pixelY, pixelX, pixelIndex, red, green, blue, pixelAlpha
  93. for ( row = 0; row < rows; row++ ) {
  94. y = ( row - 0.5 ) * res + offsetY
  95. // normalize y so shapes around edges get color
  96. pixelY = Math.max( Math.min( y, h-1), 0)
  97. for ( col = 0; col < cols; col++ ) {
  98. x = ( col - 0.5 ) * res + offsetX
  99. // normalize y so shapes around edges get color
  100. pixelX = Math.max( Math.min( x, w-1), 0)
  101. pixelIndex = ( pixelX + pixelY * w ) * 4
  102. red = imgData[ pixelIndex + 0 ]
  103. green = imgData[ pixelIndex + 1 ]
  104. blue = imgData[ pixelIndex + 2 ]
  105. pixelAlpha = alpha * ( imgData[ pixelIndex + 3 ] / 255)
  106. ctx.fillStyle = 'rgba(' + red +','+ green +','+ blue +','+ pixelAlpha + ')'
  107. switch ( opts.shape ) {
  108. case 'circle' :
  109. ctx.beginPath()
  110. ctx.arc ( x, y, halfSize, 0, TWO_PI, true )
  111. ctx.fill()
  112. ctx.closePath()
  113. break
  114. case 'diamond' :
  115. ctx.save()
  116. ctx.translate( x, y )
  117. ctx.rotate( QUARTER_PI )
  118. ctx.fillRect( -halfDiamondSize, -halfDiamondSize, diamondSize, diamondSize )
  119. ctx.restore()
  120. break
  121. default :
  122. // square
  123. ctx.fillRect( x - halfSize, y - halfSize, size, size )
  124. } // switch
  125. } // col
  126. } // row
  127. }
  128. // enable img.closePixelate
  129. HTMLImageElement.prototype.closePixelate = function ( options ) {
  130. return new ClosePixelation( this, options )
  131. }
  132. // put in global namespace
  133. window.ClosePixelation = ClosePixelation
  134. })( window );

以上这个JS文件是马赛克模糊效果的具体实现。

下面是页面上调用的JS代码:

  1. var dolly1 = document.getElementById('dolly1')
  2. var dolly2 = document.getElementById('dolly2')
  3. var dolly3 = document.getElementById('dolly3')
  4. var pixelOpts = [ { resolution: 8 } ]
  5. var pixelDolly1 = dolly1.closePixelate( pixelOpts )
  6. var pixelDolly2 = dolly2.closePixelate( pixelOpts )
  7. var pixelDolly3 = dolly3.closePixelate( pixelOpts )
  8. var range = document.getElementById('range')
  9. var output = document.getElementById('output')
  10. range.addEventListener( 'change', function( event ) {
  11. var res = parseInt( event.target.value, 10 )
  12. res = Math.floor( res / 2 ) * 2
  13. res = Math.max( 4, Math.min( 100, res ) )
  14. output.textContent = res
  15. // console.log( res );
  16. pixelOpts = [ { resolution: res } ]
  17. pixelDolly1.render( pixelOpts )
  18. pixelDolly2.render( pixelOpts )
  19. pixelDolly3.render( pixelOpts )
  20. }, false )

以上就是实现这款HTML5 Canvas图片马赛克模糊动画的全部过程。

来源:http://www.html5tricks.com/html5-canvas-image-mosaics.html
来个实例:http://qmzg.qq.com/cp/a20150604qmzg/

发表评论

表情:
评论列表 (有 0 条评论,371人围观)

还没有评论,来说两句吧...

相关阅读