2015-05-25 47 views
1

我試圖創建一個PDF在單個頁面上有一個單一的圖像。棘手的部分是使用自定義(在單獨的文件中定義)CMYK顏色空間。PdfBox - PDColorSpaceFactory.createColorSpace(document,iccColorSpace)throws nullpointerexception

我試着打電話給

PDColorSpaceFactory.createColorSpace(文件,iccColorSpace)

但繼續得到NullPointerException異常。我已經成功地跟蹤這個問題到構造函數:

public PDICCBased(PDDocument doc) 
{ 
    array = new COSArray(); 
    array.add(COSName.ICCBASED); 
    array.add(new PDStream(doc)); 
} 

PDICCBased對象有領域,這顯然沒有設置。因此,當它被調用時:

public static PDColorSpace createColorSpace(PDDocument doc, ColorSpace cs) throws IOException 
{ 
    PDColorSpace retval = null; 
    if(cs.isCS_sRGB()) 
    { 
     retval = PDDeviceRGB.INSTANCE; 
    } 
    else if(cs instanceof ICC_ColorSpace) 
    { 
     ICC_ColorSpace ics = (ICC_ColorSpace)cs; 
     PDICCBased pdCS = new PDICCBased(doc); 
     retval = pdCS; 
     COSArray ranges = new COSArray(); 
     for(int i=0; i<cs.getNumComponents(); i++) 
     { 
      ranges.add(new COSFloat(ics.getMinValue(i))); 
      ranges.add(new COSFloat(ics.getMaxValue(i))); 
     } 
     PDStream iccData = pdCS.getPDStream(); 
     OutputStream output = null; 
     try 
     { 
      output = iccData.createOutputStream(); <<<<<<<<<------------- 
      output.write(ics.getProfile().getData()); 
     } 
     finally 
     { 
      if(output != null) 
      { 
       output.close(); 
      } 
     } 
     pdCS.setNumberOfComponents(cs.getNumComponents()); 
    } 
    else 
    { 
     throw new IOException("Not yet implemented:" + cs); 
    } 
    return retval; 
} 

引發NullPointerException。

我錯過了什麼嗎?有沒有更好的方法來創建PDF使用CMYK色彩空間?

更新createColorSpace

public static PDColorSpace createColorSpace(PDDocument doc, ColorSpace cs) throws IOException 
{ 
    PDColorSpace retval = null; 
    if(cs.isCS_sRGB()) 
    { 
     retval = PDDeviceRGB.INSTANCE; 
    } 
    else if(cs instanceof ICC_ColorSpace) 
    { 
     ICC_ColorSpace ics = (ICC_ColorSpace)cs; 

     // CREATING MANUALLY THE COS ARR **************************** 
     COSArray cosArray = new COSArray(); 
     cosArray.add(COSName.ICCBASED); 
     PDStream pdStream = new PDStream(doc); 
     cosArray.add(pdStream.getStream()); 

     // USING DIFFERENT CONSTRUTOR ******************************* 
     PDICCBased pdCS = new PDICCBased(cosArray); 
     retval = pdCS; 
     COSArray ranges = new COSArray(); 
     for(int i=0; i<cs.getNumComponents(); i++) 
     { 
      ranges.add(new COSFloat(ics.getMinValue(i))); 
      ranges.add(new COSFloat(ics.getMaxValue(i))); 
     } 
     PDStream iccData = pdCS.getPDStream(); 
     OutputStream output = null; 
     try 
     { 
      output = ((COSStream)iccData.getCOSObject()).createFilteredStream(); 
      output.write(ics.getProfile().getData()); 
     } 
     finally 
     { 
      if(output != null) 
      { 
       output.close(); 
      } 
     } 
     pdCS.setNumberOfComponents(cs.getNumComponents()); 
    } 
    else 
    { 
     throw new IOException("Not yet implemented:" + cs); 
    } 
    return retval; 
} 

,從創建的顏色空間的伎倆。

ColorSpace中的從自定義ICC創建並將其應用到給定的圖像:

ICC_ColorSpace iccColorSpace = new ICC_ColorSpace(ICC_Profile.getInstance("C:\\...\\USWebCoatedSWOP.icc")); 
ColorConvertOp op = new ColorConvertOp(image.getColorModel().getColorSpace(), iccColorSpace, null); 
image = op.filter(image, null); 

的PDF的創建:

PDDocument document = new PDDocument(); 

PDColorSpace colorSpace = createColorSpace(document, iccColorSpace); 

PDPage blankPage = new PDPage(new PDRectangle(100, 100)); 
document.addPage(blankPage); 

PDPageContentStream pdPageContentStream = new PDPageContentStream(document, blankPage); 

PDXObjectImage pdxObjectImage = new PDPixelMap(document, image); 
pdxObjectImage.setColorSpace(colorSpace); 
pdPageContentStream.drawXObject(pdxObjectImage, 0, 0, imagePostScriptWidth, imagePostScriptHeight); 
pdPageContentStream.close(); 

document.save(byteArrayOutputStream); 
document.close(); 

希望這有助於。

+0

您能否包含錯誤的堆棧跟蹤? –

回答

1

好吧,這似乎是第一個構造函數的錯誤。你可以使用第二個構造函數,它採用了COSArray:

的PDF規格說明要做什麼:

「的ICCBased色彩空間應該是一個數組:[/ ICCBased流]」

所以你需要創建一個COSArray,其中第一個元素爲COSName.ICCBASED,第二個爲您的ICC數據的COSStream。創建一個COSStream並用createFilteredStream()寫入它。該COSArray可以用於第二個構造函數。

或者,只是使用PDDeviceCMYK.INSTANCE作爲色彩空間:-)

更新: 我已經打開的問題PDFBOX-2812,它已得到修復。您可以在幾小時內獲得快照here

+0

謝謝@Tilman,明白了。但是我仍然無法得到理想的結果:我設法從一個自定義icc文件生成一個PDColorSpace。我使用pdxObjectImage.setColorSpace(colorSpace)來設置圖像colorSpace和pdPageContentStream.drawXObject來寫它,但結果是質量。有什麼想法嗎? –

+0

@ Eddie-Sh無法獲得更多代碼和PDF(將其上傳到某處)。順便說一句,使用drawImage。 「但結果是一團」並不是一個很好的錯誤描述。 –

+0

用完整的代碼更新了問題。謝謝。 –