transparent image mouse collision
I am currently creating a graphical applet which is structured in following way:
publicclass Clientextends Appletimplements Runnable, MouseListener...
{
//Variable decalraions excluded
//init() excluded
publicvoid run()
{
//main loop here
}
//update() excluded
publicvoid paint(Graphics g)
{
//ALL GRAPHICS PAINTED HERE (i.e. no Swing components)
}
//mouselistener/mouseclicked etc. excluded
}
I need to implement an algorithm to determine if the mouse is over the part of an image that is NOT transparent (i.e i am using gif's, some with transparency, and it is crucial that i detect wether the mouse is over the shape within the image, and not any transparent pixels).
I have been attempting to create methods that read the pixels of an image, and using getAlpha() to determine wether the mouse point is over a non-transparent pixel, but my attempts have been unsuccessful.
If anyone knows of any good methods of doing this, it would be much appreciated. I have been researching the topic for quite a while and im stumped. I did find one tutorial at http://www.permadi.com/tutorial/javaGetImagePixels/index.html which i thought was quite useful, but when i tried to alter this demonstration to suit my situation, it couldnt do what i wanted it to (Note: this example grabs the rgb values, not the alpha values)
cheers.
[2054 byte] By [
jazza_guya] at [2007-11-27 9:21:11]

# 3
// <applet code="PixelTest" width="200" height="200"></applet>
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.GeneralPath;
import java.awt.image.BufferedImage;
public class PixelTest extends Applet {
Label label;
public void init() {
BufferedImage image = makeImage();
PixelTestCanvas canvas = new PixelTestCanvas(image);
canvas.addMouseMotionListener(mml);
setLayout(new BorderLayout());
add(canvas);
add(getLabel(), "Last");
}
private Label getLabel() {
label = new Label();
label.setAlignment(Label.CENTER);
return label;
}
private BufferedImage makeImage() {
int w = 100, h = 100;
GeneralPath path = new GeneralPath();
path.moveTo(w/2, 20);
path.lineTo(w-20, h/2);
path.lineTo(w/2, h-20);
path.lineTo(20, h/2);
path.closePath();
int type = BufferedImage.TYPE_INT_ARGB_PRE;
BufferedImage image = new BufferedImage(w, h, type);
Graphics2D g2 = image.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setPaint(Color.red);
g2.fill(path);
g2.setPaint(Color.blue);
g2.draw(path);
g2.dispose();
return image;
}
private MouseMotionListener mml = new MouseMotionAdapter() {
public void mouseMoved(MouseEvent e) {
PixelTestCanvas canvas = (PixelTestCanvas)e.getSource();
Rectangle r = canvas.loc.getBounds();
Point p = e.getPoint();
if(r.contains(p)) {
int x = p.x - r.x;
int y = p.y - r.y;
int alpha = (canvas.image.getRGB(x, y) >> 24) & 0xff;
label.setText("alpha = " + alpha);
}
}
};
}
class PixelTestCanvas extends Canvas {
BufferedImage image;
Rectangle loc;
public PixelTestCanvas(BufferedImage image) {
this.image = image;
loc = new Rectangle(image.getWidth(), image.getHeight());
}
public void paint(Graphics g) {
loc.x = (getWidth() - loc.width)/2;
loc.y = (getHeight() - loc.height)/2;
g.drawImage(image, loc.x, loc.y, this);
}
}
# 4
Thanks for your reply.
After about 3 hours of work i finally managed to successfully implement a solution for my problem, with a combination of techniques suggested by you, and on the following website:
[url]http://www.apl.jhu.edu/~hall/java/Java2D-Tutorial.html[/url]
Both examples were very helpful!
for those stuck on the same problem, i will provide the solution which i encorporated, again, comprised of techniques and code provided by crwood, and from the tutorial/demonstrations provided at the above url...
//When loading images, load them in the following manner...
Image image = getImage(getDocumentBase(), "http://127.0.0.1/example.gif);
waitForImage(image, this);
BufferedImage bufferedImage = getBufferedImage(image, this);
//In your main loop, when drawing the graphic, add something like this
//where x and y are coordinates where the image was drawn
if (mouseCollides(image, x, y) == true)
{
//reaction to the mouse being collided with the shape in the image
System.out.println("We have a collision here");
}
//Include the following 3 methods
//This method detects the alpha of the given pixel and returns true IF the pixel is NOT transparent.
public boolean mouseCollides(BufferedImage image, int imageX, int imageY)
{
boolean result = false;
if ( (mouseX >= imageX) && (mouseX < imageX+image.getWidth(this)) && (mouseY >= imageY) && (mouseY < imageY+image.getHeight(this)) )
{
int alpha = (image.getRGB(mouseX-imageX, mouseY-imageY) >> 24) & 0xff;
if (alpha == 0) { result = false; }
else {result = true; }
}
return result;
}
//This method was extracted from the url above, and simply creates a mediatracker object to wait until the image has been downloaded
public static boolean waitForImage(Image image, Component c)
{
MediaTracker tracker = new MediaTracker(c);
tracker.addImage(image, 0);
try {
tracker.waitForAll();
}
catch(InterruptedException ie)
{}
return(!tracker.isErrorAny());
}
//this method was also extracted from the url above, and is used to create a normal image, into a bufferedimage. I have altered
//it to suit my program, the type of the image being TYPE_4BYTE_ABGR
public static BufferedImage getBufferedImage(Image image, Component c)
{
BufferedImage bufferedImage = new BufferedImage(image.getWidth(c), image.getHeight(c), BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g2d = bufferedImage.createGraphics();
g2d.drawImage(image, 0, 0, c);
return(bufferedImage);
}