0

So I am trying to create a tool that can convert a .svg file type to a Java Shape or Some kind of class that will allow me to do .contains(x, y) or .contains(Rectangle2D). However I have been unable to find any methods of doing such. I found this post SVG to Java's Path2d parser this seems to give the answer but doesn’t explicitly describe how. I took a look at the classes and don't see how I would load a file then convert it to a shape. I was originally doing this with any kind of image but it turned out to be impractical and really slow. Code for that:

public static Area toArea(URL url, Color color, int tolerance) {
    return toArea(toBufferedImage(url), color, tolerance);
}

public static Area toArea(Image image, Color color, int tolerance) {
    return toArea(toBufferedImage(image), color, tolerance);
}

/**
 * Creates an Area with PixelPerfect precision
 *
 * @param image
 * @param color The color that is draws the Custom Shape
 * @param tolerance The color tolerance
 * @return Area
 */
public static Area toArea(BufferedImage image, Color color, int tolerance) {
    if (image == null) {
        return null;
    }
    Area area = new Area();
    for (int x = 0; x < image.getWidth(); x++) {
        for (int y = 0; y < image.getHeight(); y++) {
            Color pixel = new Color(image.getRGB(x, y));
            if (isIncluded(color, pixel, tolerance)) {
                Rectangle r = new Rectangle(x, y, 1, 1);
                area.add(new Area(r));
            }
        }
    }

    return area;
}

public static Area toArea(URL url) {
    return toArea(toBufferedImage(url));
}

public static Area toArea(Image image) {
    return toArea(toBufferedImage(image));
}

public static Area toArea(BufferedImage image) {
    //Assumes Black as Shape Color
    if (image == null) {
        return null;
    }

    Area area = new Area();
    Rectangle r;
    int y1, y2;

    for (int x = 0; x < image.getWidth(); x++) {
        y1 = 99;
        y2 = -1;
        for (int y = 0; y < image.getHeight(); y++) {
            Color pixel = new Color(image.getRGB(x, y));
            //-16777216 entspricht RGB(0,0,0)
            if (pixel.getRGB() == -16777216) {
                if (y1 == 99) {
                    y1 = y;
                    y2 = y;
                }
                if (y > (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;
}

private 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 static BufferedImage toBufferedImage(Image image) {
    BufferedImage buffer = new BufferedImage(image.getHeight(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);
    buffer.createGraphics().drawImage(image, null, null);
    return buffer;
}

public static BufferedImage toBufferedImage(URL url) {
    try {
        return toBufferedImage(ImageIO.read(url));
    } catch (IOException ex) {
        return null;
    }
}

private ImageShaper() {
}

Basically I am trying to write a function that can load a file that stores an irregular shape like a batman logo and then have it able to run a contains function to see if something hit it.

Community
  • 1
  • 1
  • 1
    Take a look at [Flamingo SVG trancoder enhancements](http://www.pushing-pixels.org/2008/08/24/flamingo-svg-trancoder-enhancements.html). We use this as a bases for converting SVG icons to Java classes, which are then compiled into our applications. It's based on the Apache-Batik libraries, but once compiled, we were able to remove the dependency on this project... – MadProgrammer Feb 03 '14 at 03:13
  • I am failing to understand how that deals with my problem? – user2680200 Feb 03 '14 at 05:55
  • 1
    If you're having problems with the example you've posted, try having a look at the one implemented by Kirill, it may give you some ideas – MadProgrammer Feb 03 '14 at 06:00
  • Gee that code [looks familiar](http://stackoverflow.com/q/7218309/418556), but as I recall I tried adding rectangles but found that using `lineTo` instead was significantly faster.. – Andrew Thompson Feb 04 '14 at 05:40
  • @AndrewThompson Could you provide a example? I am unsure where the lineto function is. Also, I am trying to make a function that converts an SVG to a Shape or an object that has a .contains function. I provided that code as an example of what I was previously doing. Again I am more looking for something that can parse a .svg get the points out and convert it to an object that can do .contains(x, y) ex a Shape (java.awt) – user2680200 Feb 04 '14 at 14:17
  • Do you realize that 1) 'looks familiar' is a link. 2) The linked question includes an [MCTRE](http://stackoverflow.com/help/mcve) (the last letter of which stands for **Example!**) -- I don't know how to make it easier short of coming to your house and doing it for you.. – Andrew Thompson Feb 04 '14 at 14:31
  • @AndrewThompson I apologize I did not realize that you provided a link When I responded It was late at night and I probably read past it. – user2680200 Feb 04 '14 at 17:42
  • Also @AndrewThompson did you ever modify the code to have smoother edges? Or what was your verdict on trying to achieve that. – user2680200 Feb 04 '14 at 17:58
  • No I never got around to it. :( – Andrew Thompson Feb 04 '14 at 18:00

0 Answers0