Imagem / gráfico em uma forma

Eu queria saber se existe alguma maneira de converter uma imagem / gráfico em uma Shape ? Por exemplo, posso converter o contorno de uma forma de motocicleta em uma Shape para poder usá-la em Java? Eu sei que você pode fazer isso com quadrados normais ou com cantos arredondados, polígonos, etc. Mas existe uma maneira de fazer uma forma personalizada?

motorcycle.jpg

Imagem original

motocicleta-03.png

Imagem processada

ImageOutline.java

Este código requer alguma paciência (quando em execução).

 import java.awt.*; import java.awt.image.BufferedImage; import java.awt.geom.Area; import javax.imageio.ImageIO; import java.io.File; import java.util.Date; import javax.swing.*; /* Motorcycle image courtesy of ShutterStock http://www.shutterstock.com/pic-13585165/stock-vector-travel-motorcycle-silhouette.html */ class ImageOutline { public static Area getOutline(BufferedImage image, Color color, boolean include, int tolerance) { Area area = new Area(); for (int x=0; x 

A function getArea_FastHack se no trabalho de Andrew Thompsons, que foi muito útil. O meu deve ser mais rápido, no entanto: (// Edit: e sloppier, também)

 import java.awt.*; import java.awt.geom.Area; import java.awt.image.BufferedImage; import javax.imageio.ImageIO; import java.io.File; import java.io.IOException; /** * CustomShape * based on a Class from Andrew Thompson * * Source: http://stackoverflow.com/questions/7052422/image-graphic-into-a-shape-in-java/7059497#7059497 * @author Samuel Schneider, Andrew Thompson * * */ class CustomShape { private BufferedImage image=null; /** * Creates an Area with PixelPerfect precision * @param color The color that is draws the Custom Shape * @param tolerance The color tolerance * @return Area */ public Area getArea(Color color, int tolerance) { if(image==null) return null; Area area = new Area(); for (int x=0; x(y2+1)) { r = new Rectangle(x,y1,1,y2-y1); area.add(new Area(r)); y1=y;y2=y; } y2=y; } } if((y2-y1)>=0) { r = new Rectangle(x,y1,1,y2-y1); area.add(new Area(r)); } } return area; } public static boolean isIncluded(Color target, Color pixel, int tolerance) { int rT = target.getRed(); int gT = target.getGreen(); int bT = target.getBlue(); int rP = pixel.getRed(); int gP = pixel.getGreen(); int bP = pixel.getBlue(); return( (rP-tolerance< =rT) && (rT<=rP+tolerance) && (gP-tolerance<=gT) && (gT<=gP+tolerance) && (bP-tolerance<=bT) && (bT<=bP+tolerance) ); } public CustomShape(String path) { try { BufferedImage image = ImageIO.read(new File(path)); this.image = image; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } 

Aqui está algo mais rápido, mas menos preciso, útil para checagem de colisão ou física 2D.

  Point[] MakePoly(BufferedImage spr,int d,int angle){ //creates an outline of a transparent image, points are stored in an array //arg0 - BufferedImage source image //arg1 - Int detail (lower = better) //arg2 - Int angle threshold in degrees (will remove points with angle differences below this level; 15 is a good value) // making this larger will make the body faster but less accurate; int w= spr.getWidth(null); int h= spr.getHeight(null); // increase array size from 255 if needed int[] vertex_x=new int[255], vertex_y=new int[255], vertex_k=new int[255]; int numPoints=0, tx=0,ty=0,fy=-1,lx=0,ly=0; vertex_x[0]=0; vertex_y[0]=0; vertex_k[0]=1; for (tx=0;tx>24) != 0x00 ) {vertex_x[numPoints]=tx; vertex_y[numPoints]=h-ty; vertex_k[numPoints]=1; numPoints++; if (fy<0) fy=ty; lx=tx; ly=ty; break; } for (ty=0;ty=0;tx-=1) if((spr.getRGB(tx,ty)>>24) != 0x00 && ty > ly) {vertex_x[numPoints]=tx; vertex_y[numPoints]=h-ty; vertex_k[numPoints]=1; numPoints++; lx=tx; ly=ty; break; } for (tx=w-1;tx>=0;tx-=d) for (ty=h-1;ty>=0;ty-=1) if((spr.getRGB(tx,ty)>>24) != 0x00 && tx < lx) {vertex_x[numPoints]=tx; vertex_y[numPoints]=h-ty; vertex_k[numPoints]=1; numPoints ++; lx=tx; ly=ty; break; } for (ty=h-1;ty>=0;ty-=d) for (tx=0;tx>24) != 0x00 && ty < ly && ty > fy) {vertex_x[numPoints]=tx; vertex_y[numPoints]=h-ty; vertex_k[numPoints]=1; numPoints ++; lx=tx; ly=ty; break; } double ang1,ang2; for (int i=0;i