Sharpening an Image


The next button is the Sharpen button, which sharpens an image by accenting the borders between colors. You can see image.gif after it has been sharpened in Figure 3.5 (the sharpening may not be totally evident with the limited-resolution image in the figure, but it's very clear when you run the Graphicizer and click the Sharpen button).

Figure 3.5. Sharpening an image.


As with embossing an image, you have to work pixel by pixel to sharpen an image. That could mean a lot of work, as you just saw when embossing. However, if you don't want to do anything too fancy, there's an easier way to work pixel by pixel and combine a pixel with its surrounding neighborsyou can use the Kernel class and the ConvolveOp class to do the work for you.

The Kernel class lets you define a matrix that specifies how a pixel should be combined with the other pixels around it to produce a new result, and the ConvolveOp class lets you apply a kernel to a BufferedImage object, pixel by pixel.

You can see the significant methods of the Kernel object in Table 3.6 and the significant methods of the ConvolveOp class in Table 3.7.

Table 3.6. The Significant Methods of the java.awt.image.Kernel Class

Method

Does This

int getHeight()

Returns the height of the matrix specified by this Kernel object

float[] getKernelData(float[] data)

Returns the kernel data as an array

int getWidth()

Returns the width of the matrix specified by this Kernel object

int getXOrigin()

Returns the X origin of the data in this Kernel object

int getYOrigin()

Returns the Y origin of the data in this Kernel object


Table 3.7. The Significant Methods of the java.awt.image.ConvolveOp Class

Method

Does This

 BufferedImage createCompatibleDestImage (BufferedImage src, ColorModel destCM) 

Creates a compatible destination image

 BufferedImage filter(BufferedImage src, BufferedImage dst) 

Performs a convolution operation on BufferedImage objects

 WritableRaster filter(Raster src, WritableRaster dst) 

Performs a convolution operation on Raster objects

Rectangle2D getBounds2D(BufferedImage src)

Returns the rectangle specifying the bounds of the destination image

Rectangle2D getBounds2D(Raster src)

Returns the rectangle specifying the bounds of the destination raster

int getEdgeCondition()

Returns the edge condition, which specifies how you want to handle the edges of the image

Kernel getKernel()

Returns the Kernel object used by this ConvolveOp object


Here's how this all works for sharpening an image when the Sharpen button is clicked. After storing the present buffered image in the image backup, bufferedImageBackup (in case the user wants to undo the sharpening operation), the code creates a new kernel for the operation.

A kernel is really a matrix that will multiply a pixel and its neighbors. Here is the kernel you can use to sharpen the image; you pass the Kernel constructor thee dimensions of the matrix and then the matrix itself:

 public void actionPerformed(ActionEvent event) {     .     .     .         if(event.getSource() == button2){             bufferedImageBackup = bufferedImage;             Kernel kernel =                 new Kernel(3, 3, new float[] {                     0.0f, -1.0f,  0.0f,                     -1.0f,  5.0f, -1.0f,                     0.0f, -1.0f,  0.0f                 });         .         .         . 

Now you've got to apply the new kernel to the image, which you do with the ConvolveOp class's filter method. As you'll recall, there were problems when embossing the image with the pixels at the edge of the image, because what we did involved combining pixels with their neighbors. To handle that situation when filtering with ConvolveOp, you can pass the filter method the constant ConvolveOp.EDGE_NO_OP, which means that pixels at the edge of the image will be copied to the destination image without modification. (The other option is ConvolveOp.EDGE_ZERO_FILL, which means that pixels at the edge of the destination image will be set to zero.)

You also can pass an object to the ConvolveOp constructor that will give ConvolveOp some hints on how to draw the image, but that's not needed here. Therefore, the code just passes null as the third parameter to the ConvolveOp constructor:

 public void actionPerformed(ActionEvent event) {     .     .     .         if(event.getSource() == button2){             bufferedImageBackup = bufferedImage;             Kernel kernel =                 new Kernel(3, 3, new float[] {                     0.0f, -1.0f,  0.0f,                     -1.0f,  5.0f, -1.0f,                     0.0f, -1.0f,  0.0f                 });             ConvolveOp convolveOp =                 new ConvolveOp(                     kernel, ConvolveOp.EDGE_NO_OP, null);         .         .         . 

Now you're ready to sharpen the image with the filter method. You pass this method a source image and a destination image, and after the filtering is done, the code will copy the new image over into the image displayed by Graphicizer, bufferedImage, and repaint that image this way:

 public void actionPerformed(ActionEvent event) {     .     .     .         if(event.getSource() == button2){             bufferedImageBackup = bufferedImage;             Kernel kernel =                 new Kernel(3, 3, new float[] {                     0.0f, -1.0f,  0.0f,                     -1.0f,  5.0f, -1.0f,                     0.0f, -1.0f,  0.0f                 });             ConvolveOp convolveOp =                 new ConvolveOp(                     kernel, ConvolveOp.EDGE_NO_OP, null);             BufferedImage temp = new BufferedImage(                 bufferedImage.getWidth(), bufferedImage.getHeight(),                 BufferedImage.TYPE_INT_ARGB);             convolveOp.filter(bufferedImage, temp);             bufferedImage = temp;             repaint();         } 

That's all it takes; the results appear in Figure 3.5.



    Java After Hours(c) 10 Projects You'll Never Do at Work
    Java After Hours: 10 Projects Youll Never Do at Work
    ISBN: 0672327473
    EAN: 2147483647
    Year: 2006
    Pages: 128

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net