Объединение четырех изображений CMYK в одно изображение RGB Java

Заранее спасибо за любую помощь, которую вы могли бы мне оказать, и извините за мой плохой английский.

Я знаю, что есть много вопросов по этой теме, но я много просмотрел весь Интернет (и StackOverflow тоже), но я не нашел ответа на этот вопрос...

У меня есть четыре изображения; каждый из них находится в цветовой модели TYPE_BYTE_GRAY. Я загрузил эти четыре изображения, используя этот код:

int numElems = 4;
BufferedImage[] img = new BufferedImage[numElems];
for(int i=0;i<numElems;i++){
    FileInputStream in = new FileInputStream(args[i]);
    img[i] = ImageIO.read(in);
    in.close();
}

Просто прочитайте ImageIO... Мне нужно "объединить" четыре изображения в одно изображение RGB... Каждое из изображений представляет собой один канал из изображения CMYK. Все эти изображения имеют равные размеры. Я преобразовал четыре изображения в одно изображение CMYK, используя этот код:

for(int j=0;j<img[0].getHeight();j++){
    //Read current point color...
    for(int k=0;k<numElems;k++){
        colPunto[k] = (img[k].getRGB(i, j) & 0xFF);
    }

    int colorPunto = convertComponentsRGB(colPunto);

    //Now, I set the point...
    out.setRGB(i, j, colorPunto);
    }
}

Эта функция «convertComponentsRGB» — это просто естественная математика для преобразования цвета CMYK в цвет RGB...

function convertComponentsRGB(int[] pointColor){
float cyan = (float)pointColor[0] / (float)255;
float magenta = (float)pointColor[1] / (float)255;
float yellow = (float)pointColor[2] / (float)255;
float black = (float)pointColor[3] / (float)255;

float c = min(1f,cyan * (1f - black) + black); //minimum value
float m = min(1f,magenta * (1f - black) + black); //minimum value
float y = min(1f, yellow * (1f - black) + black); //minimum value

result[0] = Math.round(255f*(1f - c));
result[1] = Math.round(255f*(1f - m));
result[2] = Math.round(255f*(1f - y));

    return (result[0]<<16) | (result[1]<<8) | result[2];
}

Проблема здесь... в скорости. Обработка одного изображения занимает 12 секунд, потому что мы должны прочитать каждый пиксель и записать каждый пиксель, и я думаю, что функции «getRGB» и «setRGB» не очень быстрые (или это просто лучший способ добиться этого) .

¿Как я могу этого добиться? Я много читал про ColorModel, фильтры, но так и не понял, как добиться этого в более подходящее время.


person epilefreyes    schedule 04.06.2012    source источник
comment
Вы можете вычислить 1/255f один раз для всех изображений и использовать его при умножении вместо деления. Попробуйте и отчитайтесь. :)   -  person Marcus Johansson    schedule 04.06.2012
comment
Хорошо... лучше на 10%... Но дело в том, что я хочу знать, есть ли способ добиться этого с помощью растровых изображений, фильтров или чего-то в этом роде... Чистый Java2D   -  person epilefreyes    schedule 04.06.2012
comment
Вам даже не нужны поплавки. Я предполагаю, что это могло бы быть примерно в 10 раз быстрее, если бы вы делали это только с целыми числами.   -  person Marcus Johansson    schedule 04.06.2012
comment
Извините за вопрос, но... как? Любые идеи?   -  person epilefreyes    schedule 04.06.2012
comment
Нет... одинаковое время для преобразования... Я не уверен, что целые числа или числа с плавающей запятой имеют разное время...   -  person epilefreyes    schedule 04.06.2012
comment
Можно ли сделать все, используя целые числа, как в red=255-cyan; green=255-magenta; blue=255-yellow, а затем масштабировать для черного цвета путем (а) умножения каждого результата на (255-black) и (б) деления каждого результата на 255?   -  person Jim Garrison    schedule 04.06.2012
comment
По моему опыту, getRGB и setRGB действительно медленные. Чтение и запись буферов данных напрямую — ваш лучший способ повысить производительность.   -  person lhballoti    schedule 04.06.2012


Ответы (1)


Вы можете использовать getData и setData для ускорения доступа к пикселям по сравнению с getRGB и setRGB.

Нет необходимости преобразовывать CMYK в числа с плавающей запятой и обратно, вы можете работать напрямую со значениями пикселей:

function convertComponentsRGB(int[] pointColor){
    int r = max(0, 255 - (pointColor[0] + pointColor[3]));
    int g = max(0, 255 - (pointColor[1] + pointColor[3]));
    int b = max(0, 255 - (pointColor[2] + pointColor[3]));

    return (r<<16) | (g<<8) | b;
}
person Mark Ransom    schedule 04.06.2012