Как из BufferedImage - перевести картинку в пиксели?

216
14 мая 2017, 22:33

как из BufferedImage - перевести картинку в пиксели?

Использую... javax.imageio.ImageIO - умеет грузить картинки как объекты BufferedImage. javax.swing.JLabel - умеет отображать иконки. javax.swing.ImageIcon - умеет загружать картинки как иконки. BufferedImage - там есть методы манипуляции с пикселями, а вот как проводить анализ - уже сложнее.

Answer 1

Для получения массива пикселей из объекта класса BufferedImage можно использовать следующий способ:

private static int[][] convertTo2DWithoutUsingGetRGB(BufferedImage image) {
    final byte[] pixels = ((DataBufferByte) 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) {
        final int pixelLength = 4;
        for (int pixel = 0, row = 0, col = 0; pixel < pixels.length; pixel += pixelLength) {
            int argb = 0;
            argb += (((int) pixels[pixel] & 0xff) << 24); // alpha
            argb += ((int) pixels[pixel + 1] & 0xff); // blue
            argb += (((int) pixels[pixel + 2] & 0xff) << 8); // green
            argb += (((int) pixels[pixel + 3] & 0xff) << 16); // red
            result[row][col] = argb;
            col++;
            if (col == width) {
                col = 0;
                row++;
            }
        }
    } else {
        final int pixelLength = 3;
        for (int pixel = 0, row = 0, col = 0; pixel < pixels.length; pixel += pixelLength) {
            int argb = 0;
            argb += -16777216; // 255 alpha
            argb += ((int) pixels[pixel] & 0xff); // blue
            argb += (((int) pixels[pixel + 1] & 0xff) << 8); // green
            argb += (((int) pixels[pixel + 2] & 0xff) << 16); // red
            result[row][col] = argb;
            col++;
            if (col == width) {
                col = 0;
                row++;
            }
        }
    }
    return result;
}

Данный метод основан на использовании объекта класса DataBufferByte с последующим получением из него массива пикселей.

Также, в классе BufferedImage есть метод getRGB(...), который возвращает цвет заданного пикселя в модели RGB.

С помощью него можно получить массив цветов пикселей:

int[][] pixelsArray = new int[w][h];
for (int i=0; i<w; i++) {
    for(int j=0; j<h; j++) {
        pixelsArray[i][j] = bufferedImage.getRGB(i, j);
    }
}

, где w и h – размеры изображения в пикселях, а bufferedImage – объект класса BufferedImage.

Однако, если Вам нужно получить массив всех пикселей, то целесообразно использовать первый способ, так как он более эффективный (хоть и не такой очевидный).

Answer 2

Для того чтобы представить BufferedImage в виде массива пикселей, можно воспользоваться классом PixelGrabber и его методом grabPixels(). Например так:

void grabPixels(BufferedImage image) {
 int[] pixels;
 int width = image.getWidth();
 int height = image.getHeight();
 try {
  pixels = new int[width * height];
  PixelGrabber pgb = new PixelGrabber(image, 0, 0, width, height, pixels, 0, width);
  pgb.grabPixels();
 } catch (InterruptedException exc) {
  System.out.println("Interrupted: " + exc.getMessage());
 }
 //Ваш код
}

Перед этим нужно импортировать класс PixelGrabber. Например так:

import java.awt.image.PixelGrabber;

В строке //Ваш код Вам будет доступен одномерный массив pixels содержащий в себе все пиксели изображения image. Если же нужен массив двумерный можно обращаться точке (x;y) по формуле pixels[y * width + x] или написать небольшой конвертер. Например так:

int[][] pixels2D = int[width][height];
for(int y = 0; y < height; y++) {
 for(int x = 0; x < width; x++) {
  pixels2D[x][y] = pixels[y * width + x];
 }
}
//Ваш код 2

В строке //Ваш код 2 Вам будет доступен двумерный массив pixels2D. Обратиться к пикселю (x;y) можно, например так:

pixels2D[x][y]

Конструктор PixelGrabber:

PixelGrabber(Image изображение, int слева, int сверху, int ширина,
 int высота, int массив[], int смещение, int ширина_строки_развертки)

Сигнатура метода grabPixels():

boolean grabPixels() throws InterruptedException
boolean grabPixels(long время_ожидания_пикселей_в_миллисекундах) throws
 InterruptedException
READ ALSO
Ошибка с RecyclerView: No adapter attached; skipping layout

Ошибка с RecyclerView: No adapter attached; skipping layout

Собственно проблема следующаяЕсть активность которая сначала загружает первый фрагмент:

311
Какую СУБД выбрать?

Какую СУБД выбрать?

Доброго времени всемНужна помощь по выбору базы данных

222
Вывод данных из массива в таблицу

Вывод данных из массива в таблицу

Как сделать вывод данных в таблицу javafx из массивов ?

208