获取彩色边框之间所有像素的算法?

时间:2017-08-18 18:23:46

标签: java algorithm graphics

我有一个长png文件,连续包含许多精灵,但它们的宽度/高度稍有变化。但是,所有精灵都有一个固定的蓝色1px边框。

然而,在每个精灵之后,边框彼此连接2px(只是在相互作用的边界之后的边界),请参阅:

img

但是在精灵的底部,它错过了一个像素点

是否有现有的算法可以在给出像素时获得这样的颜色边框之间的所有像素, 包括边框

或者其他任何想法如何抓住这样一个文件的所有精灵并给它们一个固定的大小?

2 个答案:

答案 0 :(得分:1)

我拍了你的照片并对其进行了改造以符合你的描述。

在纯文本中,我从左到右依次表示并指出可能表示图像开始或结束的行,并使用跟踪器变量来确定哪个是哪个。

我在Java中这样做了:

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.io.File;
import java.io.IOException;

public class PixelArtSizeFinder {
    public static void main(String[] args) throws IOException {
        File imageFile = new File("pixel_boat.png");
        BufferedImage image = ImageIO.read(imageFile);

        int w = image.getWidth();
        int h = image.getHeight();
        System.out.format("Size: %dx%d%n", w, h);

        Raster data = image.getData();

        int objectsFound = 0;
        int startObjectWidth = 0;
        int endObjectWidth = 0;
        boolean scanningObject = false;
        for (int x = 0; x < w; x++) {

            boolean verticalLineContainsOnlyTransparentOrBorder = true;
            for (int y = 0; y < h; y++) {
                int[] pixel = data.getPixel(x, y, new int[4]);
                if (isOther(pixel)) {
                    verticalLineContainsOnlyTransparentOrBorder = false;
                }
            }

            if (verticalLineContainsOnlyTransparentOrBorder) {
                if (scanningObject) {
                    endObjectWidth = x;
                    System.out.format("Object %d: %d-%d (%dpx)%n",
                            objectsFound,
                            startObjectWidth,
                            endObjectWidth,
                            endObjectWidth - startObjectWidth);
                } else {
                    objectsFound++;
                    startObjectWidth = x;
                }
                scanningObject ^= true; //toggle
            }
        }
    }

    private static boolean isTransparent(int[] pixel) {
        return pixel[3] == 0;
    }

    private static boolean isBorder(int[] pixel) {
        return pixel[0] == 0 && pixel[1] == 187 && pixel[2] == 255 && pixel[3] == 255;
    }

    private static boolean isOther(int[] pixel) {
        return !isTransparent(pixel) && !isBorder(pixel);
    }
}

,结果是

Size: 171x72
Object 1: 0-27 (27px)
Object 2: 28-56 (28px)
Object 3: 57-85 (28px)
Object 4: 86-113 (27px)
Object 5: 114-142 (28px)
Object 6: 143-170 (27px)

答案 1 :(得分:0)

我不知道是否已存在任何算法或功能,但您可以做的是: 虽然船只是相同的,你想要获得两个蓝色像素之间的所有像素,所以你可以使用这样的东西:

 for all i in vertical pixels 
    for all j in horizontal pixels 
        if pixel(i,j) == blue then 
           j = j+ 1 
            while pixel(i,j) != blue then 
              you save this pixel in an array for example 
              j = j+1
            end while 
         end if 
     end for 
 end for 

这只是一个想法,肯定不是最优的,但你可以使用它并执行它以使其更好;)