How do you crop an image?
I thought I got it and again, I failed.
publicvoid actionPerformed(ActionEvent evt){
if (evt.getActionCommand().toLowerCase().trim().equals("crop")){
cropPanel.setImage(
(BufferedImage)createImage(
new FilteredImageSource(cropPanel.getImage().getSource(),
new CropImageFilter((int)cropPanel.getClip().getX(),
(int)cropPanel.getClip().getY(),
(int)cropPanel.getClip().getWidth(),
(int)cropPanel.getClip().getHeight()))));
repaint();
hasCropped =true;
}
}
This constantly throws the following exception:
Exception in thread"AWT-EventQueue-0" java.lang.ClassCastException: sun.awt.image.ToolkitImage cannot be cast to java.awt.image.BufferedImage
at com.ppowell.tools.imagetools.ImageCropper.actionPerformed(ImageCropper.java:180)
I was under the impression that I'm using java.awt.Image, where did sun.awt.image.ToolkitImage come from? I can't figure out how to cast this correctly either, what do I do?
Thanx
Phil
Ok I updated the code:
public void crop() {
ImageCropper.this.cropPanel.setImage(
ImageCropper.this.cropPanel.getImage().getSubimage(
(int)ImageCropper.this.cropPanel.getClip().getX(),
(int)ImageCropper.this.cropPanel.getClip().getY(),
(int)ImageCropper.this.cropPanel.getClip().getWidth(),
(int)ImageCropper.this.cropPanel.getClip().getHeight()));
ImageCropper.this.cropPanel.setup();
ImageCropper.this.validate();
}
}
And now I get this exception:
Exception in thread "AWT-EventQueue-0"
java.awt.image.RasterFormatException: (x + width) is outside of Raster
at
sun.awt.image.ByteInterleavedRaster.createWritableChild(ByteInterleavedRaster.java:
1230)
at java.awt.image.BufferedImage.getSubimage(BufferedImage.java:
1156)
What is the width and height of the image (cropPanel.getImage()) ?For the clip rectangle:what is the value of X?what is the value of Y?what is the width?what is the height?
> What is the width and height of the image
> (cropPanel.getImage()) ?
width 418
height 374
> For the clip rectangle:
> what is the value of X?
218
> what is the value of Y?
389
> what is the width?
> what is the height?
Same as above
> > What is the width and height of the image
> > (cropPanel.getImage()) ?
>
> width 418
> height 374
>
> > For the clip rectangle:
> > what is the value of X?
>
> 218
>
> > what is the value of Y?
>
> 389
>
> > what is the width?
> > what is the height?
>
> Same as above
I don't understand. Cropping is the following: if you have a 300x300 image and you want the middle 1/9 of the image (think tictactoe):
x==100, y=100, width==100, heigh==100
If instead I kept width==300, height==300, the "subimage" would hang over the right and bottom edges of the original image. With x==100 and y==100,
the largest the subimage can be is width==200, height==200.
>> what is the width?
>> what is the height?
> Same as above.
It can't be the same as above.
The width of the cropped image is the width of the image less the 'x' value of the cropped image's origin, less any cropping of the RH margin.
And so forth correspondingly for the height.
ejpa at 2007-7-10 12:09:19 >

> >> what is the width?
> >> what is the height?
>
> > Same as above.
>
> It can't be the same as above.
It's the same as above. Don't ask me why.
>
> The width of the cropped image is the width of the
> image less the 'x' value of the cropped image's
> origin, less any cropping of the RH margin.
>
> And so forth correspondingly for the height.
I know why. There's something wrong with what your image crop panel is telling you. It is given you nonsensical dimensions.
ejpa at 2007-7-10 12:09:19 >

> I know why. There's something wrong with what your
> image crop panel is telling you. It is given you
> nonsensical dimensions.
Would it help if I point you to the original image and you can try for yourself:
http://valsignalandet.com/images/cemetery_potluck_3/flyer.jpg
Maybe if you all can try you might be able to get more reliable dimensions than I could and help me figure out how I can do the same for myself
It wouldn't help at all. The problem is with your image crop panel. Fix it.
ejpa at 2007-7-10 12:09:19 >

> It wouldn't help at all. The problem is with your> image crop panel. Fix it.interesting way of trying to get 10 duke points
> interesting way of trying to get 10 duke points
Interesting way of trying to solve your problem, and an even less interesting way of treating people who are trying to help you.
If I really was trying to get your 10 duke points, which I'm not interested in either, downloading your image wouldn't help. The point you don't seem to have grasped is that the problem is in the code. Where does this image crop panel come from? It's not in the JDK. Whatever it is, it is broken if it is delivering you those dimensions.
Or possibly you are using it incorrectly. Possibly you should be subtracting the x value from the width yourself, and the y value from the height.
ejpa at 2007-7-10 12:09:19 >

Got it, thanx
/**
* Perform crop
* <a href="http://forum.java.sun.com/thread.jspa?threadID=627125&messageID=3587532">Reference</a>
*/
public void crop() {
Rectangle r = ImageCropper.this.cropPanel.getClip();
if (!this.isClipInsideImage(r)) /* AVOID RasterFormatException */ {
return;
}
// offset clip from view to raster model
int x = (ImageCropper.this.cropPanel.getWidth() -
ImageCropper.this.cropPanel.getImage().getWidth()) / 2;
int y = (ImageCropper.this.cropPanel.getHeight() -
ImageCropper.this.cropPanel.getImage().getHeight()) / 2;
BufferedImage clippedImage =
ImageCropper.this.cropPanel.getImage().getSubimage(
(int)r.getX() - x,
(int)r.getY() - y,
(int)r.getWidth(),
(int)r.getHeight());
ImageCropper.this.cropPanel.setImage(clippedImage);
ImageCropper.this.cropPanel.setup();
ImageCropper.this.validate();
}
/**
* Determine if the {@link java.awt.image.BufferedImage} has a legitimate {@link java.awt.Rectangle} clip
* To avoid {@link java.awt.image.RasterFormatException}
* @param r {@link java.awt.Rectangle}
* @return {@link java.lang.Boolean}
* <a href="http://forum.java.sun.com/thread.jspa?threadID=627125&messageID=3587532">Reference</a>
*/
private boolean isClipInsideImage(Rectangle r) {
int w = ImageCropper.this.cropPanel.getWidth();
int h = ImageCropper.this.cropPanel.getHeight();
int imageWidth = ImageCropper.this.cropPanel.getImage().getWidth();
int imageHeight = ImageCropper.this.cropPanel.getImage().getHeight();
int x = (w - imageWidth) / 2;
int y = (h - imageHeight) / 2;
if ((int)r.getX() >= x &&
(int)r.getX() + (int)r.getWidth() <= x + imageWidth &&
(int)r.getY() >= y &&
(int)r.getY() + (int)r.getHeight() <= y + imageHeight) {
return true;
}
return false;
}
Even better I think:
/**
* Perform crop
* <a href="http://forum.java.sun.com/thread.jspa?threadID=627125&messageID=3587532">Reference</a>
*/
public void crop() {
Rectangle r = ImageCropper.this.cropPanel.getClip();
// OFFSET CLIP FROM VIEW TO RASTER MODEL
try {
int x = (ImageCropper.this.cropPanel.getWidth() -
ImageCropper.this.cropPanel.getImage().getWidth()) / 2;
int y = (ImageCropper.this.cropPanel.getHeight() -
ImageCropper.this.cropPanel.getImage().getHeight()) / 2;
BufferedImage clippedImage =
ImageCropper.this.cropPanel.getImage().getSubimage(
(int)r.getX() - x,
(int)r.getY() - y,
(int)r.getWidth(),
(int)r.getHeight());
ImageCropper.this.cropPanel.setImage(clippedImage);
ImageCropper.this.cropPanel.setup();
ImageCropper.this.validate();
} catch (RasterFormatException e) /* CLIP IS OUT OF BOUNDS */ {
JOptionPane.showMessageDialog(
ImageCropper.this, "Your selection is out of bounds of the image",
"Invalid Selection",
JOptionPane.ERROR_MESSAGE);
ImageCropper.this.cropPanel.resetClip();
}
}
