MotionBlurOp.java 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /*
  2. ** Copyright 2005 Huxtable.com. All rights reserved.
  3. */
  4. package com.cvte.blurfilter;
  5. import java.awt.*;
  6. import java.awt.geom.*;
  7. import java.awt.image.*;
  8. public class MotionBlurOp extends AbstractBufferedImageOp {
  9. private float centreX = 0.5f, centreY = 0.5f;
  10. private float distance;
  11. private float angle;
  12. private float rotation;
  13. private float zoom;
  14. public MotionBlurOp() {
  15. }
  16. public MotionBlurOp( float distance, float angle, float rotation, float zoom ) {
  17. this.distance = distance;
  18. this.angle = angle;
  19. this.rotation = rotation;
  20. this.zoom = zoom;
  21. }
  22. public void setAngle( float angle ) {
  23. this.angle = angle;
  24. }
  25. public float getAngle() {
  26. return angle;
  27. }
  28. public void setDistance( float distance ) {
  29. this.distance = distance;
  30. }
  31. public float getDistance() {
  32. return distance;
  33. }
  34. public void setRotation( float rotation ) {
  35. this.rotation = rotation;
  36. }
  37. public float getRotation() {
  38. return rotation;
  39. }
  40. public void setZoom( float zoom ) {
  41. this.zoom = zoom;
  42. }
  43. public float getZoom() {
  44. return zoom;
  45. }
  46. public void setCentreX( float centreX ) {
  47. this.centreX = centreX;
  48. }
  49. public float getCentreX() {
  50. return centreX;
  51. }
  52. public void setCentreY( float centreY ) {
  53. this.centreY = centreY;
  54. }
  55. public float getCentreY() {
  56. return centreY;
  57. }
  58. public void setCentre( Point2D centre ) {
  59. this.centreX = (float)centre.getX();
  60. this.centreY = (float)centre.getY();
  61. }
  62. public Point2D getCentre() {
  63. return new Point2D.Float( centreX, centreY );
  64. }
  65. private int log2( int n ) {
  66. int m = 1;
  67. int log2n = 0;
  68. while (m < n) {
  69. m *= 2;
  70. log2n++;
  71. }
  72. return log2n;
  73. }
  74. public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
  75. if ( dst == null )
  76. dst = createCompatibleDestImage( src, null );
  77. BufferedImage tsrc = src;
  78. float cx = (float)src.getWidth() * centreX;
  79. float cy = (float)src.getHeight() * centreY;
  80. float imageRadius = (float)Math.sqrt( cx*cx + cy*cy );
  81. float translateX = (float)(distance * Math.cos( angle ));
  82. float translateY = (float)(distance * -Math.sin( angle ));
  83. float scale = zoom;
  84. float rotate = rotation;
  85. float maxDistance = distance + Math.abs(rotation*imageRadius) + zoom*imageRadius;
  86. int steps = log2((int)maxDistance);
  87. translateX /= maxDistance;
  88. translateY /= maxDistance;
  89. scale /= maxDistance;
  90. rotate /= maxDistance;
  91. if ( steps == 0 ) {
  92. Graphics2D g = dst.createGraphics();
  93. g.drawRenderedImage( src, null );
  94. g.dispose();
  95. return dst;
  96. }
  97. BufferedImage tmp = createCompatibleDestImage( src, null );
  98. for ( int i = 0; i < steps; i++ ) {
  99. Graphics2D g = tmp.createGraphics();
  100. g.drawImage( tsrc, null, null );
  101. g.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
  102. g.setRenderingHint( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR );
  103. g.setComposite( AlphaComposite.getInstance( AlphaComposite.SRC_OVER, 0.5f ) );
  104. g.translate( cx+translateX, cy+translateY );
  105. g.scale( 1.0001+scale, 1.0001+scale ); // The .0001 works round a bug on Windows where drawImage throws an ArrayIndexOutofBoundException
  106. if ( rotation != 0 )
  107. g.rotate( rotate );
  108. g.translate( -cx, -cy );
  109. g.drawImage( dst, null, null );
  110. g.dispose();
  111. BufferedImage ti = dst;
  112. dst = tmp;
  113. tmp = ti;
  114. tsrc = dst;
  115. translateX *= 2;
  116. translateY *= 2;
  117. scale *= 2;
  118. rotate *= 2;
  119. }
  120. return dst;
  121. }
  122. public String toString() {
  123. return "Blur/Motion Blur...";
  124. }
  125. }