创建图像非透明部分的多边形

Create polygon of non-transparent parts of image

我想要实现的是获取 image 的掩码,将其转换为尺寸为 (image.getWidth(), image.getHeight())Array,然后获取所有像素并查看它们是否具有 0 的 alpha 值。

如果他们这样做,那么:

其他:

到目前为止,我知道如何编程。如果您有兴趣,这是我正在使用的代码:

private int[] createMask(BufferedImage image) {

    final int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
    final int width = image.getWidth();
    final int height = image.getHeight();
    final boolean hasAlphaChannel = image.getAlphaRaster() != null;

    int[][] result = new int[height][width];
    if (hasAlphaChannel) {
        for (int pixel = 0, row = 0, col = 0; pixel < pixels.length; pixel += 4) {
            int alpha = pixels[pixel];
            if(alpha != 0) {
                result[row][col] = 1;
            } else {
                result[row][col] = 0;
            }

            if (col == width) {
                col = 0;
                row++;
            }
        } 
    }

    return result;
}

在我得到这个掩码后,我试图使用这个 Array 通过这个代码或者它的一个替代(从 http://docs.oracle.com/javase/tutorial/2d/geometry/arbitrary.html 获得)来绘制一个 Polygon

    int x1Points[] = {0, 100, 0, 100};
    int y1Points[] = {0, 50, 50, 0};
    GeneralPath polygon = 
    new GeneralPath(GeneralPath.WIND_EVEN_ODD,
                    x1Points.length);
    polygon.moveTo(x1Points[0], y1Points[0]);

    for (int index = 1; index < x1Points.length; index++) {
        polygon.lineTo(x1Points[index], y1Points[index]);
    };

    polygon.closePath();
    g2.draw(polygon);

但是,我需要创建一个方法,该方法为我提供 Array 中的所有坐标,该坐标由 Point 个对象组成,以绕过图像以实质上创建一个 "mask" .

    public Point[] getCords(int[] mask) {
        ArrayList<Point> points = new ArrayList<Point>(); //you can change this to whatever you want to use

        //get coords to surround the mask
        // >> involving `0` (for transparent) and `1` (non transparent) 
        //  >> these are contained in the `mask` Array...

        return points.toArray(new Points[0]);

所以,总结一下:

(link 到下面的相关 java 代码)

要创建蒙版边界,请执行以下操作:对于每对坐标 (x,y),检查其 8 个相邻点中是否有任何一个在蒙版之外。但是,请记住,生成的遮罩不一定是 1 像素宽,矢量化可能是 non-trivial,如本例所示(白色是遮罩区域,红色是遮罩内的遮罩边框,黑色未遮罩面积):

幸运的是,即使您在蒙版的某些地方得到了 wider-than-1 像素的边框,您也可以通过从该蒙版中拒绝蒙版的某些像素来构建可多边形的子蒙版来解决此问题。下图以蓝色显示子掩码的边框:

我前段时间实现了这样的算法。有您可以使用的代码,但它与我的解决方案紧密结合,但是您可以从中找到一些见解:Thick mask border resolution。它的想法是,从初始掩码开始,您通过 flood-filling 原始掩码构建子掩码,并使用谓词检查子掩码边界的单元格是否最多有 2 个基本方向邻居(顺序方向邻居在这里无关紧要)。

获得蓝色子掩码的边界后,构建一个图形,其中顶点是子掩码边界的点,边缘位于主要相邻点之间。然后遍历该图的每个组件,对于每个组件,您都会得到一个构成多边形的点列表。