Преобразовать 8-битный байтовый массив изображения в градациях серого в BufferedImage

Просто подумайте «о манжете», так сказать.

Не могли бы вы организовать их в 2 списка, один для начала интервалов, а другой для конца интервалов.

Таким образом, вы можете сравнить y с элементами в начале списка интервалов (например, бинарным поиском), чтобы сократить кандидатов на основе этого.

Затем вы можете сравнить x с элементами в конце Список интервалов.

EDIT

Случай: Once Off

Если вы сравниваете только один интервал с перечнем интервалов в я не считаю, что сортировка поможет вам , так как идеальная сортировка - это O (n) .

Выполняя линейный поиск по всем x, чтобы обрезать любые невозможные интервалы, а затем выполнение другого линейного поиска через оставшиеся y, вы можете уменьшить свою общую работу. Хотя это все еще O (n), без этого вы бы делали 2n сравнения, тогда как в среднем вы делали бы это (3n-1) / 2 таким образом.

Я считаю, что это лучший вы можете сделать для несортированного списка.

Случай: предварительная сортировка не считается

В случае, когда вы будете повторно сравнивать отдельные интервалы с этот список интервалов и ваш предварительный сортировка списка, вы можете добиться лучших результатов. Этот процесс все еще применяется, но, выполняя двоичный поиск в первом списке, а затем вы можете получить O (m log n) в отличие от O (mn), где m - количество сравниваемых единичных интервалов. Обратите внимание, что все еще дает вам преимущество сокращения общих сравнений. [2m log n по сравнению с m (3 (log n) - 1) / 2]

0
задан Alexander Shaw 18 January 2019 в 10:47
поделиться

2 ответа

Мне удалось выполнить преобразование для разрешения 640x480 следующим образом:

BufferedImage image = new BufferedImage(640,480,BufferedImage.TYPE_BYTE_INDEXED);

int i = 0;
for(int y = 0; y < 480; y++)
{
    for(int x = 0; x < 640; x++)
    {
        int g = imageBytes[i++] & 0xFF;
        image.setRGB(x,y,new Color(g,g,g).getRGB());
    }
}

EDIT: удален бесполезный код (спасибо Marco13)

0
ответ дан Alexander Shaw 18 January 2019 в 10:47
поделиться

Есть два хороших способа сделать это, в зависимости от вашего варианта использования.

Либо создайте новое, серое изображение, и скопируйте в него данные. Это будет держать изображение «управляемым», что может привести к лучшей производительности рендеринга (т.е. на экране). Но для этого потребуется вдвое больше памяти и скопировать данные из вашего ввода в изображение.

Другой способ - создать серое изображение непосредственно «вокруг» существующих данных пикселей. Это будет быстрее и практически не использует лишнюю кучу, поскольку позволяет избежать копирования данных пикселей. Но изображение не будет управляемым (так как резервный массив открыт и изменчив).

Обе опции показаны ниже:

int w = 640;
int h = 480;

byte[] imageBytes = new byte[w * h];

// 1 Keeps the image "managed" at the expense of twice the memory + a large array copy
BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_GRAY);
image.getRaster().setDataElements(0, 0, w, h, imageBytes);

System.out.println("image: " + image);

// 2 Faster, and uses less memory, but will make the image "unmanaged"
ColorModel cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY), false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
WritableRaster raster = Raster.createInterleavedRaster(new DataBufferByte(imageBytes, imageBytes.length), w, h, w, 1, new int[]{0}, null);
BufferedImage image2 = new BufferedImage(cm, raster, cm.isAlphaPremultiplied(), null);

System.out.println("image2: " + image2);

Если данные изображения не находятся в линейном пространстве серого цвета, можно использовать IndexColorModel для отображения входных данных в любой диапазон, который вы хотите: [117 ]

// Alternate, using IndexColorModel, if your input isn't in linear gray color space
int[] cmap = new int[256]; // TODO: Add ARGB packed colors here...
IndexColorModel icm = new IndexColorModel(8, 256, cmap, 0, false, -1, DataBuffer.TYPE_BYTE);

// As 1
BufferedImage image3 = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_INDEXED, icm);
image3.getRaster().setDataElements(0, 0, w, h, imageBytes);
System.out.println("image3: " + image3);

// As 2
BufferedImage image4 = new BufferedImage(icm, raster, cm.isAlphaPremultiplied(), null);

System.out.println("image4: " + image4);
0
ответ дан haraldK 18 January 2019 в 10:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: