简体   繁体   中英

Algorithm to get all pixels between color border?

I have a long png file containing many sprites in a row, but their width/height changes by a little bit. However, all sprites have a fixed blue color 1px border around it.

However, after each sprite, the borders are connected to each other by 2px (just border after border that interacts) see this:

IMG

But at the bottom of the sprites, it misses one pixel point

Is there an existing algorithm that can get all pixels between a color border like this, including the border when giving the pixels?

Or any other ideas how to grab all sprites of one file like this and give them a fixed size?

I took your image and transformed it to match your description.

In plain text I went form left to right and identify lines that might indicate a start or end to an image and used a tracker variable to decide which is which.

I approached it like this in 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);
    }
}

and the result was

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)

I don't know if any algorithm or function already exists for this but what you can do is : while the boats are all the same and you wanna get all the pixels between two blue pixels so you can use something like this :

 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 

This is just an idea and for sure not the most optimal but you can you use it and perform it to make it better ;)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM