Алгоритм заливки, приводящий к черному изображению

Я создаю алгоритм заливки, который, надеюсь, в конце концов найдет лицо в центре фотографии на основе цвета в точном центре и похожих цветов, окружающих его. На данный момент, однако, мой алгоритм должен взять любой цвет в пределах массива int и перенести его в массив-держатель, по сути создав копию оригинального изображения. Но это не работает, и в результате я получаю черное изображение. Кто-нибудь может увидеть проблему, которую мне не хватает?

public class TemplateMaker {

public static void main(String[] args) throws IOException {
    importPhoto();
}

public static void importPhoto() throws IOException {
    File imgPath = new File("/Pictures/BaseImage.JPG");
    BufferedImage bufferedImage = ImageIO.read(imgPath);
    establishArray(bufferedImage);
}

public static void establishArray(BufferedImage bufferedImage) throws IOException {
    //byte[] pixels = hugeImage.getData();
    int width = bufferedImage.getWidth();
    System.out.println(width);
    int height = bufferedImage.getHeight();
    System.out.println(height);
    int[][] result = new int[height][width];
    for (int i = 0; i < height; i++)
        for (int j = 0; j < width; j++) {
            result[i][j] = bufferedImage.getRGB(j, i);
        }
    findFace(result);
}

public static void findFace(int[][] image) throws IOException {
    int height = image.length;
    int width = image[0].length;
    Color centerStart = new Color(image[height / 2][width / 2], true);
    System.out.println(centerStart.getRGB());
    System.out.println(Color.blue.getRGB());

    int[][] filled = new int[height][width];

    floodFill(height / 2, width / 2, centerStart, image, filled, height, width);

    //construct the filled array as image.
    BufferedImage bufferImage2 = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    for (int x = 0; x < height; x++) {
        for (int y = 0; y < width; y++) {
            bufferImage2.setRGB(y, x, filled[x][y]);
        }
    }
    //save filled array as image file
    File outputfile = new File("/Pictures/saved.jpg");
    ImageIO.write(bufferImage2, "jpg", outputfile);
}

public static int[][] floodFill(int x, int y, Color targetColor, int[][] image, int[][] filled, int height, int width) {

    //execute something similar once algorithm works. 
    // if (image[x][y] < targetColor.getRGB()/2 || image[x][y] > targetColor.getRGB()*2) return filled;

    if (image[x][y] == Color.blue.getRGB()) {
        return filled;
    }
    if (image.length < 0 || image[0].length < 0 || image.length >= height || image[0].length >= width) {
        return filled;
    }
    filled[x][y] = image[x][y];
    image[x][y] = Color.blue.getRGB();

    floodFill(x - 1, y, targetColor, image, filled, height, width);
    floodFill(x + 1, y, targetColor, image, filled, height, width);
    floodFill(x, y - 1, targetColor, image, filled, height, width);
    floodFill(x, y + 1, targetColor, image, filled, height, width);
    return filled;
}

}

1 ответ

Решение

Вы создаете int[][] с именем fill, а затем вызываете floodFill(...), который возвращает, ничего не делая с массивом. image.length всегда равен height, а image[0].length всегда равно width, поэтому всегда возвращается со второго оператора if.

Затем вы строите BufferedImage из этого пустого массива и записываете его в файл. Все значения в массиве инициализируются в 0, что дает вам черный цвет.

Изменение цикла for в findFace(..) на приведенное ниже приведет к сохранению исходного изображения из вашего массива держателей.

        for (int x = 0; x < height; x++) {
        for (int y = 0; y < width; y++) {
            bufferImage2.setRGB(y, x, image[x][y]);
        }
    }

Но я не уверен, спрашиваешь ты об этом или нет.

Изменить: Попробуйте это и посмотрите, если он отправит вас в правильном направлении:

    public static int[][] floodFill(int x, int y, Color targetColor, int[][] image, int[][] filled, int height, int width) {

    //execute something similar once algorithm works. 
    // if (image[x][y] < targetColor.getRGB()/2 || image[x][y] > targetColor.getRGB()*2) return filled;

    if (image[x][y] == Color.blue.getRGB()) {
        System.out.println("returned if 1");
        return filled;
    }
    /*if (image.length < 0 || image[0].length < 0 || image.length >= height || image[0].length >= width) {
        return filled;
    }*/
    filled[x][y] = image[x][y];
    image[x][y] = Color.blue.getRGB();

    if (x - 1 <= 0 && y < width) {
        floodFill(x - 1, y, targetColor, image, filled, height, width);
    }

    if(x + 1 < height && y >= 0 && y < width) {
        floodFill(x + 1, y, targetColor, image, filled, height, width);
    }

    if(x >= 0 && x < height && y - 1 <= 0) {
        floodFill(x, y - 1, targetColor, image, filled, height, width);
    }

    if(x >= 0 && x < height && y + 1 < width) {
        floodFill(x, y + 1, targetColor, image, filled, height, width);
    }

    return filled;
}
Другие вопросы по тегам