我有一个jFrame,它包含一个图像(即图像的像素),它使用repaint()根据算法不断更新。
现在我想在一个点出现时停止重绘(),在这个点上像素中不再发生更改。我还想将最终输出保存为图像(.jpg)。
任何想法或解决方案?
在备用行中两次在ImageWindow构造函数中输入图像路径。相同的文件路径。
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;
}
}
运行程序时,您会逐渐找到图像的平滑处理。我希望程序在图像中的更改停止时将最终输出存储为图像(.jpg)。