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]
# 1
Take a look at PixelGrabber API: http://java.sun.com/j2se/1.5.0/docs/api/java/awt/image/PixelGrabber.htmlThere's an example at the beginning showing how to find the alpha of a pixel.
Rodney_McKaya at 2007-7-12 22:14:53 > top of Java-index,Security,Cryptography...
# 2

Thanks for your reply.

I have already researched the PixelGrabber class, but my attempts to use it have been unsuccessful... I have been unable to adapt it to my situation. I cant really provide any code, as my application is too big to provide small snippets without taking the code out of context.

A working demonstration of loading an image (say 100 by 100 pixels), and displaying the ALPHA value of pixel located at point, say (3,4) , would solve my problem. Does anyone know of such a demonstration or example that does this?

Cheers

jazza_guya at 2007-7-12 22:14:53 > top of Java-index,Security,Cryptography...
# 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);

}

}

crwooda at 2007-7-12 22:14:53 > top of Java-index,Security,Cryptography...
# 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);

}

jazza_guya at 2007-7-12 22:14:53 > top of Java-index,Security,Cryptography...