2013-10-23 60 views
2

我一直在嘗試兩天來找到一種方法將CMYK圖像完美轉換爲Java中的RGB圖像。我經歷了很多不同的方式來完成它,所有這些都在網絡上找到,其中一些在Stackoverflow上,但我不能找到簡單的方法,並且沒有這種轉換的典型顏色褪色。 。我知道像Photoshop或Irfanview這樣的工具可以在兩次點擊中完美實現,但我希望它能夠被Java編碼。好吧,長話短說,我找到了一種方法,就在這裏。將圖像從CMYK轉換爲Java中的RGB

+0

爲此,請從您的問題中刪除答案並自己回答您的問題。如果你想分享你的知識,那就是它的意思。 –

+0

完成。那麼,在7個小時內回答... – Erwann

+0

爲什麼在七個小時內?哦......是的,當你創建一個問題時,如果你想立即回答,你可以標記它。如果您先發布您的問題,然後嘗試添加解決方案,那麼可能確實不可能。 –

回答

0

你試過了什麼答案,發現工作不正常?

他們有沒有給出這個例子的代碼。它會產生褪色嗎?你能不能分享一個示例圖像鏈接產生問題?

/** 
* ImageIO cannot read CMYK-jpegs, it throws IIOException(Unsupported Image Type). 
* This method tries to read cmyk image. 
* @param file 
* @return image TYPE_4BYTE_ABGR 
* @throws Exception 
*/ 
public static BufferedImage readCMYKImage(File file) throws Exception { 
    Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName("JPEG"); 
    ImageReader reader = null; 
    while(readers.hasNext()) { 
     reader = readers.next(); 
     if(reader.canReadRaster()) 
      break; 
    } 

    FileInputStream fis = new FileInputStream(file); 
    try { 
     ImageInputStream input = ImageIO.createImageInputStream(fis); 
     reader.setInput(input); // original CMYK-jpeg stream 
     Raster raster = reader.readRaster(0, null); // read image raster 
     BufferedImage image = new BufferedImage(raster.getWidth(), raster.getHeight(), BufferedImage.TYPE_4BYTE_ABGR); 
     image.getRaster().setRect(raster); 
     return image; 
    } finally { 
     try { fis.close(); } catch(Exception ex) {} 
    } 
} 
+0

如果沒有獲取通常嵌入CMYK JPEG文件中的ICC顏色配置文件,則無法進行正確的轉換。這裏發佈的代碼只是假定CMYK數據是ABGR,它看起來不像意圖...我建議你看看http://stackoverflow.com/a/12132805/1428606和http://stackoverflow.com/a/16149142/1428606 :-) – haraldK

1

感謝您的反饋。

誰,我試過你的方式,但是無論是使用ImageIO.write()還是JAI.create()保存圖像,它都給了我倒置或非常奇怪的顏色。

haraldk,我還沒有試過你的代碼呢。我看了一下,看起來並不簡單。我稍後再試一試。同時,請允許我張貼我自己的方式,這實際上是由其他人的方式組成的(這個人:https://stackoverflow.com/a/9470843/2435757和其他人:http://www.coderanch.com/t/485449/java/java/RGB-CMYK-Image等等)組成的組。它可以工作,但是,當創建一個新的BufferedImage時,分辨率或壓縮方法(對於TIFF圖像)等信息都會丟失並且必須重置,而這種方法不會(我認爲只需要非JRE庫這裏是Apache的常見xmlgraphics):

BufferedImage img = null; 
try { 
    img = ImageIO.read(new File("cmyk.jpg")); 
} catch (IOException e) {} 

ColorSpace cmyk = DeviceCMYKColorSpace.getInstance(); 
int w = img.getWidth(), h = img.getHeight(); 
BufferedImage image = null; 
byte[] buffer = ((DataBufferByte) img.getRaster().getDataBuffer()).getData(); 
int pixelCount = buffer.length; 
byte[] new_data = new byte[pixelCount/4 * 3]; 
float lastC = -1, lastM = -1, lastY = -1, lastK = -1; 
float C, M, Y, K; 
float[] rgb = new float[3]; 
// loop through each pixel changing CMYK values to RGB 
int pixelReached = 0; 

for (int i = 0 ; i < pixelCount ; i += 4) { 
    C = (buffer[i] & 0xff)/255f; 
    M = (buffer[i + 1] & 0xff)/255f; 
    Y = (buffer[i + 2] & 0xff)/255f; 
    K = (buffer[i + 3] & 0xff)/255f; 
    if (lastC == C && lastM == M && lastY == Y && lastK == K) { 
     //use existing values if not changed 
    } else { //work out new 
     rgb = cmyk.toRGB(new float[] {C, M, Y, K}); 
     //cache values 
     lastC = C; 
     lastM = M; 
     lastY = Y; 
     lastK = K; 
    } 
    new_data[pixelReached++] = (byte) (rgb[0] * 255); 
    new_data[pixelReached++] = (byte) (rgb[1] * 255); 
    new_data[pixelReached++] = (byte) (rgb[2] * 255); 
} 

// turn data into RGB image 
image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); 
int[] l_bandoff = {0, 1, 2}; 
PixelInterleavedSampleModel l_sm = new PixelInterleavedSampleModel(DataBuffer.TYPE_INT, w, h, 3, w * 3, l_bandoff); 
image.setData(new ByteInterleavedRaster(l_sm, new DataBufferByte(new_data, new_data.length), new Point(0, 0))); 

// write 
ImageIO.write(image, "jpg", new File("rgb.jpg")); 

上面的代碼讓我對JPEG和TIFF圖像效果出色,雖然我偶然得到一個特定的形象很奇怪的結果。

這裏是另一個,更簡單和直接,方式,通過JMagick:

ImageInfo info = new ImageInfo("cmyk.tif"); 
MagickImage image = new MagickImage(info); 
image.transformRgbImage(ColorspaceType.CMYKColorspace); 
image.setFileName("rgb.tif"); 
image.writeImage(info); 

無法縮短,可能嗎?同樣適用於JPEG和TIFF的魅力。

不,haraldk,我沒有使用任何對顏色配置文件的引用。這對我來說似乎也很奇怪。我只能假設這兩種方式都使用默認的顏色配置文件,並且我很幸運,因爲它迄今爲止在所有情況下都能正常工作。

我正在等待您對此的反饋。

乾杯。 PS:我會很高興給你鏈接到我使用的圖像,但Stackoverflow說我不夠可靠:-)在另一篇文章中,也許,如果你需要它們。

相關問題