Here you can find the source of imageToShape(BufferedImage image)
public static Shape imageToShape(BufferedImage image)
//package com.java2s; /*/*w w w. j a v a 2 s .co m*/ * Copyright (C) 2010-2016 JPEXS, All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3.0 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. */ import java.awt.Polygon; import java.awt.Shape; import java.awt.geom.Area; import java.awt.image.BufferedImage; import java.awt.image.DataBufferInt; import java.util.ArrayList; import java.util.BitSet; import java.util.HashMap; import java.util.List; import java.util.Map; public class Main { private static final Map<BitSet, Area> shapeCache = new HashMap<>(); public static Shape imageToShape(BufferedImage image) { Area area = new Area(); int width = image.getWidth(); int height = image.getHeight(); int[] imgData; int type = image.getType(); if (type == BufferedImage.TYPE_INT_ARGB_PRE || type == BufferedImage.TYPE_INT_RGB) { imgData = ((DataBufferInt) image.getRaster().getDataBuffer()) .getData(); } else { imgData = image.getRGB(0, 0, width, height, null, 0, width); } BitSet bs = new BitSet(width * height); bs.set(type); int pixelCount = width * height; for (int i = 0; i < pixelCount; i++) { if ((imgData[i] >>> 24) > 0) { bs.set(i); } } if (shapeCache.containsKey(bs)) { return shapeCache.get(bs); } BitSet bsArea = new BitSet(width * height); boolean modified = true; List<Integer> leftCoordsX = new ArrayList<>(); List<Integer> leftCoordsY = new ArrayList<>(); List<Integer> rightCoordsX = new ArrayList<>(); List<Integer> rightCoordsY = new ArrayList<>(); while (modified) { modified = false; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int idx = width * y + x; if ((imgData[idx] >>> 24) > 0 && !bsArea.get(idx)) { leftCoordsX.clear(); leftCoordsY.clear(); rightCoordsX.clear(); rightCoordsY.clear(); int leftX = x; int rightX = findRight(imgData, x, y, width); leftCoordsX.add(leftX); leftCoordsY.add(y); rightCoordsX.add(rightX); rightCoordsY.add(y); setBitSet(bsArea, leftX, rightX, y, width); int y2 = y + 1; while (y2 < height) { leftCoordsX.add(leftX); leftCoordsY.add(y2); rightCoordsX.add(rightX); rightCoordsY.add(y2); int leftX2 = findFirst(imgData, leftX, rightX, y2, width); if (leftX2 == -1) { break; } int rightX2 = findRight(imgData, leftX2, y2, width); if (leftX2 != leftX) { leftCoordsX.add(leftX2); leftCoordsY.add(y2); } if (rightX2 != rightX) { rightCoordsX.add(rightX2); rightCoordsY.add(y2); } leftX = leftX2; rightX = rightX2; setBitSet(bsArea, leftX, rightX, y2, width); y2++; } int cnt = leftCoordsX.size() + rightCoordsX.size(); int[] xCoords = new int[cnt]; int[] yCoords = new int[cnt]; for (int i = 0; i < rightCoordsX.size(); i++) { xCoords[i] = rightCoordsX.get(i); yCoords[i] = rightCoordsY.get(i); } int offset = rightCoordsX.size(); for (int i = 0; i < leftCoordsX.size(); i++) { int idx2 = leftCoordsX.size() - i - 1; xCoords[i + offset] = leftCoordsX.get(idx2); yCoords[i + offset] = leftCoordsY.get(idx2); } Area area2 = new Area(new Polygon(xCoords, yCoords, xCoords.length)); area.add(area2); modified = true; } } } } shapeCache.put(bs, area); return area; } private static int findRight(int[] imgData, int x, int y, int width) { int result = x; int idx = width * y + x; while (result < width && (imgData[idx] >>> 24) > 0) { result++; idx++; } return result; } private static void setBitSet(BitSet bitSet, int x1, int x2, int y, int width) { int idx = width * y + x1; int idx2 = width * y + x2; for (; idx < idx2; idx++) { bitSet.set(idx); } } private static int findFirst(int[] imgData, int x1, int x2, int y, int width) { int idx = width * y + x1; if ((imgData[idx] >>> 24) > 0) { while (x1 > 0 && (imgData[idx - 1] >>> 24) > 0) { x1--; idx--; } return x1; } int idx2 = width * y + x2; for (; idx < idx2; idx++) { if ((imgData[idx] >>> 24) > 0) { return x1; } x1++; } return -1; } }