0

I have a jFrame which contains an image (i.e. pixels of an image), which keeps on updating according to the algorithm using repaint().

Now I want to stop repaint() when a point comes, at which there are no more changes occuring in the pixels.Also I want to save the final output as an image (.jpg).

Any ideas or solution?

Enter the image path in ImageWindow constructor twice in alternate lines. Same file path.

   package smart_blur;

   import java.awt.Graphics;
   import java.awt.image.BufferedImage;
   import java.io.File;
   import javax.imageio.ImageIO;
   import javax.swing.JComponent;
   import javax.swing.JFrame;

   public final class ImageWindow 
{

   // This inner class is our canvas.
   // We draw the image on it.
   class ImagePanel extends JComponent 
   {

    BufferedImage theImage = null;

    ImagePanel( BufferedImage image )           
    {
            super();
            theImage = image;
    }

    public BufferedImage getImage( ) 
    {
            return theImage;
    }

    public void setImage( BufferedImage image ) 

    {
            theImage = image;
            this.updatePanel();
    }

    public void updatePanel() 
    {

            invalidate();
            getParent().doLayout();
            repaint();
    }

    @Override
    public void paintComponent( Graphics g ) 
    {

            int w = theImage.getWidth( );
            int h = theImage.getHeight( );

         Boolean t=   g.drawImage( theImage, 0,0, this.getWidth(),this.getHeight(), this );

    }

  }  // end ImagePanel inner class

    // Constructor
    public ImageWindow( String [] args ) {

    // open image
    BufferedImage image = openImageFile( "DSC_0008.jpg" );

    // create a panel for it
    ImagePanel theImagePanel  = new ImagePanel( image );

    // display the panel in a JFrame
    createWindowForPanel( theImagePanel, "DSC_0008.jpg" );

    // filter the image
    filterImage( theImagePanel );
  }

   public void filterImage( ImagePanel panel ) {

    SmartBlurFilter filter = new SmartBlurFilter( );

    BufferedImage newImage = filter.filter( panel.getImage( ) );

    panel.setImage( newImage );


   }

   public void createWindowForPanel( ImagePanel theImagePanel, String name ) {

    BufferedImage image = theImagePanel.getImage();
    JFrame mainFrame = new JFrame();
    mainFrame.setTitle( name );       
    mainFrame.setBounds(0,0,image.getWidth( )+10, image.getHeight( )+10);
    mainFrame.setDefaultCloseOperation(3);
    mainFrame.getContentPane().add( theImagePanel );
    mainFrame.setVisible(true);
   }

   BufferedImage openImageFile( String fname ) {

    BufferedImage img = null;

    try {
            File f = new File( fname );
            if ( f.exists( ) )
            img = ImageIO.read(f);
    }
    catch (Exception e) {
            e.printStackTrace();
    }

    return img;
  }
public static void main( String[] args ) 
{
       ImageWindow imageWindow = new ImageWindow( args ); 
}
}

SmartBlurFilter.java

 package smart_blur;


 import java.awt.image.Kernel;
 import java.awt.image.BufferedImage;
 import java.awt.image.ConvolveOp;
 import java.awt.Graphics;

public class SmartBlurFilter {

  double SENSITIVITY = 10;
  int REGION_SIZE = 5;

 float [] kernelArray = {
       1,1,1,1,1,1,1,1,1,
       1,1,1,1,1,1,1,1,1,
       1,1,1,1,1,1,1,1,1,
       1,1,1,1,1,1,1,1,1,
       1,1,1,1,1,1,1,1,1,
       1,1,1,1,1,1,1,1,1,
       1,1,1,1,1,1,1,1,1,
       1,1,1,1,1,1,1,1,1,
       1,1,1,1,1,1,1,1,1
  };

  Kernel kernel = new Kernel( 9,9, normalizeKernel( kernelArray ) );

  float [] normalizeKernel( float [] ar ) {
       int n = 0;
       for (int i = 0; i < ar.length; i++)
       n += ar[i];
       for (int i = 0; i < ar.length; i++)
       ar[i] /= n;

       return ar;
  }

  public double lerp( double a,double b, double amt) {
       return a + amt * ( b - a );
  }

  public double getLerpAmount( double a, double cutoff ) {

       if ( a > cutoff )
       return 1.0;

       return a / cutoff;
  }

    public double rmsError( int [] pixels ) {

       double ave = 0;

       for ( int i = 0; i < pixels.length; i++ )
       ave += ( pixels[ i ] >> 8 ) & 255;

       ave /= pixels.length;

       double diff = 0;
       double accumulator = 0;

       for ( int i = 0; i < pixels.length; i++ ) {
               diff = ( ( pixels[ i ] >> 8 ) & 255 ) - ave;
               diff *= diff;
               accumulator += diff;
       }

       double rms = accumulator / pixels.length;

       rms = Math.sqrt( rms );

       return rms;
  }

  int [] getSample( BufferedImage image, int x, int y, int size ) {

       int [] pixels = {};

       try {
               BufferedImage subimage = image.getSubimage( x,y, size, size );
               pixels = subimage.getRGB( 0,0,size,size,null,0,size );
       }
       catch( Exception e ) {
               // will arrive here if we requested
               // pixels outside the image bounds
       }
       return pixels;
  }

    int lerpPixel( int oldpixel, int newpixel, double amt ) {

       int oldRed = ( oldpixel >> 16 ) & 255;
       int newRed = ( newpixel >> 16 ) & 255;
       int red = (int) lerp( (double)oldRed, (double)newRed, amt ) & 255;

       int oldGreen = ( oldpixel >> 8 ) & 255;
       int newGreen = ( newpixel >> 8 ) & 255;
       int green = (int) lerp( (double)oldGreen, (double)newGreen, amt ) & 255;

       int oldBlue = oldpixel & 255;
       int newBlue = newpixel & 255;
       int blue = (int) lerp( (double)oldBlue, (double)newBlue, amt ) & 255;

       return ( red << 16 ) | ( green << 8 ) | blue;
  }

  int [] blurImage( BufferedImage image,
  int [] orig, int [] blur, double sensitivity ) {

       int newPixel = 0;
       double amt = 0;
       int size = REGION_SIZE;

       for ( int i = 0; i < orig.length; i++ ) {
               int w = image.getWidth();
               int [] pix = getSample( image, i % w, i / w, size );
               if ( pix.length == 0 )
               continue;

               amt = getLerpAmount ( rmsError( pix ), sensitivity );
               newPixel = lerpPixel( blur[ i ], orig[ i ],  amt );
               orig[ i ] = newPixel;
       }

       return orig;
    }


   public BufferedImage filter( BufferedImage image ) {

       ConvolveOp convolver = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP,
       null);

       // clone image into target
       BufferedImage target = new BufferedImage(image.getWidth(), image
       .getHeight(), image.getType());
       Graphics g = target.createGraphics();
       g.drawImage(image, 0, 0, null);

       g.dispose();

       int w = target.getWidth();
       int h = target.getHeight();

       // get source pixels
       int [] pixels = image.getRGB(0, 0, w, h, null, 0, w);

       // blur the cloned image
       target = convolver.filter(target, image);
                 // target = convolver.;


       // get the blurred pixels
       int [] blurryPixels = target.getRGB(0, 0, w, h, null, 0, w);

       // go thru the image and interpolate values
       pixels = blurImage(image, pixels, blurryPixels, SENSITIVITY);

       // replace original pixels with new ones
       image.setRGB(0, 0, w, h, pixels, 0, w);
       return image;
     }
  }

When you run the program, you will find smoothing of the image gradually. I want to the program to store the final output as an image (.jpg) when changes in the image stop.

  • 4
    Plenty, probably none of which would be useful to you, but if you provided a [runnable example](https://stackoverflow.com/help/mcve) which demonstrated what you are doing, it would help focus our solutions – MadProgrammer Mar 27 '14 at 23:00
  • For better help sooner, post an [MCVE](http://stackoverflow.com/help/mcve) (Minimal Complete and Verifiable Example). An MCVE should be one source file, but can contain more than one class. One way to get image(s) for an example is to hot-link to the images seen in [this answer](http://stackoverflow.com/a/19209651/418556). – Andrew Thompson Mar 28 '14 at 20:42
  • As an aside. *"`openImageFile( "DSC_0008.jpg" );`"* By the time of deployment, those resources will likely become an [tag:embedded-resource]. That being the case, the resource must be accessed by `URL` instead of `File`. See the [info page](http://stackoverflow.com/tags/embedded-resource/info) for the tag, for a way to form an `URL`. – Andrew Thompson Mar 28 '14 at 20:43

0 Answers0