2017-05-03 3 views
0

나는 pdf 파일을 pdf 형식으로 만들기 위해 pdf 파일을 사용하고있다. PDShadingType4 클래스 사용. 아래는 코드 구현이지만 빈 PDF 만 만들었습니다. 아파치에서 제공되는 예제에서 PDShadingType4 구현을 찾지 못했습니다.PDShadingType4 Apache를 사용하는 Type 4 음영 구현 PDF 상자

생성 된 삼각형은 내가 PDShadingType4를 사용하는 쉐이딩 예를 찾을 수 없습니다 나는 아파치 PDF 상자 issue

에서 발견된다 link에서 PDF의 왼쪽 아래에있는 삼각형처럼 보일 것입니다.

구현이 잘못 되었습니까? 또는이 코드는 왼쪽 하단에 고우 러드 음영 삼각형 생성 PDShadingType4

 

    import java.io.IOException; 
    import org.apache.pdfbox.cos.COSArray; 
    import org.apache.pdfbox.cos.COSFloat; 
    import org.apache.pdfbox.cos.COSInteger; 
    import org.apache.pdfbox.cos.COSName; 
    import org.apache.pdfbox.cos.COSStream; 
    import org.apache.pdfbox.pdmodel.PDDocument; 
    import org.apache.pdfbox.pdmodel.PDPage; 
    import org.apache.pdfbox.pdmodel.PDPageContentStream; 
    import org.apache.pdfbox.pdmodel.common.function.PDFunctionType2; 
    import org.apache.pdfbox.pdmodel.graphics.color.PDDeviceRGB; 
    import org.apache.pdfbox.pdmodel.graphics.shading.PDShading; 
    import org.apache.pdfbox.pdmodel.graphics.shading.PDShadingType4; 

    public class TriangleGraident2 { 

     public void create(String file) throws IOException { 
      PDDocument document = null; 
      try { 
       document = new PDDocument(); 
       PDPage page = new PDPage(); 
       document.addPage(page); 

       PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, false); 

       contentStream.moveTo(38, 17); 

       COSStream fdict = new COSStream(); 
       fdict.setInt(COSName.FUNCTION_TYPE, 2); 

       COSArray cosArray = new COSArray(); 
       cosArray.add(COSInteger.get(104)); 
       cosArray.add(COSInteger.get(83)); 
       cosArray.add(COSInteger.get(170)); 
       cosArray.add(COSInteger.get(17)); 
       cosArray.add(COSInteger.get(38)); 
       cosArray.add(COSInteger.get(17)); 


       /*Setting color */ 
       COSArray c0 = new COSArray(); 
       c0.add(COSFloat.get("1")); 
       c0.add(COSFloat.get("0")); 
       c0.add(COSFloat.get("0")); 
       COSArray c1 = new COSArray(); 
       c1.add(COSFloat.get("0.5")); 
       c1.add(COSFloat.get("1")); 
       c1.add(COSFloat.get("0.5")); 
       /*Setting color*/ 


       COSArray decode = new COSArray(); 
       decode.add(COSFloat.get("0.0")); 
       decode.add(COSFloat.get("1.0")); 
       decode.add(COSFloat.get("0.0")); 
       decode.add(COSFloat.get("1.0")); 
       decode.add(COSFloat.get("0.0")); 

       fdict.setItem(COSName.C0, c0); 
       fdict.setItem(COSName.C1, c1); 

       PDFunctionType2 func = new PDFunctionType2(fdict); 
       PDShadingType4 shading = new PDShadingType4(fdict); 
       shading.setColorSpace(PDDeviceRGB.INSTANCE); 
       shading.setShadingType(PDShading.SHADING_TYPE4); 

       shading.getCOSObject().setInt(COSName.LENGTH, 32); 

       shading.setBitsPerCoordinate(24); 
       shading.setBitsPerComponent(16); 
       shading.setBitsPerFlag(8); 
       shading.getCOSObject().setItem(COSName.COORDS, cosArray); 
       shading.setDecodeValues(decode); 
       shading.setFunction(func); 
       contentStream.shadingFill(shading); 
       contentStream.close(); 
       document.save(file); 
       document.close(); 

      } 
      finally { 
       if (document != null) { 
        document.close(); 
       } 
      } 
     } 

     public static void main(String[] args) throws IOException { 
      TriangleGraident2 creator = new TriangleGraident2(); 
      creator.create("C:\\Users\\abc\\Desktop\\triangle_image.pdf"); 
     } 
    } 

+0

우연히도 내가 쉐이딩을 만들었지 만 PostScript로 만든 다음 ghostscript로 PDF로 변환했습니다. 정말로 타입 4 음영이 필요합니까? 그리고 2 (축 방향) 또는 3 (방사형)을 입력하지 않았습니까? 이 두 가지는 PDFBox 소스 코드에 예제가 있고 유형 4 음영은 그렇지 않기 때문에 어렵습니다. 유형 4 음영은 언급 한 것과 같은 삼각형입니다. 대개 삼각형 모양을 만들기 위해 거대한 톤을가집니다. 코드가 스트림을 잃어 버렸습니다. PDF 사양을 참조하십시오 ... 색상, 좌표 및 플래그가 포함되어 있습니다. 아주 까다로운 일. –

+0

당신은 또한 함수 물건이 필요하지 않습니다, 그것은 필요하지 않습니다, 당신은 그것을 사용하지 않음으로써 더 다채로운 삼각형을 얻을 수 있습니다. (왜냐하면 함수를 사용한다면, 삼각형의 각 모서리는 1 값이 될 것이고, 그러면 함수에 의해 n 색 요소로 변환되어 3 개의 "극한값"을 얻기가 어렵습니다.) 스트림의 내용은 f x y c1 ... cn입니다 (스펙의 p190 참조). 정말로 필요한 경우 데모를 구현할 수 있습니다. –

+0

예 선생님 4 형 음영이 필요합니다. 또한 당신이 만든 링크에서 당신이 언급 한대로 PDF 사양을 읽은 후에 유형 4 음영을 시도했습니다. 그러나 복잡 해지고 있습니다. 링크 또는 정점 설정 방법에 대한 설명서를 찾을 수 없습니다. 삼각형의 위의 코드를 수정하거나 작성한 삼각형의 코드에 대한 링크를 제공 할 수 있습니까? 내게 매우 유용 할 것입니다. 유형 2 (축 방향) 또는 유형 3 (방사형)을 사용하여 삼각형을 만들 수 없다고 생각합니다.) 쉐이딩. 그리고이 후에 폴리곤을 그릴 필요가 있습니다. 그래서 저는 Type 4 음영으로 작업하고있었습니다 – user3194123

답변

2

를 사용하여 음영 (삼각형)을 달성하기 위해 다른 방법들이 있습니다 : 전화,

// See PDF 32000 specification, 
// 8.7.4.5.5 Type 4 Shadings (Free-Form Gouraud-Shaded Triangle Meshes) 
PDShadingType4 gouraudShading = new PDShadingType4(new COSStream()); 
gouraudShading.setShadingType(PDShading.SHADING_TYPE4); 
// we use multiple of 8, so that no padding is needed 
gouraudShading.setBitsPerFlag(8); 
gouraudShading.setBitsPerCoordinate(16); 
gouraudShading.setBitsPerComponent(8); 
COSArray decodeArray = new COSArray(); 
// coordinates x y map 16 bits 0..FFFF to 0..FFFF to make your life easy 
// so no calculation is needed, but you can only use integer coordinates 
// for real numbers, you'll need smaller bounds, e.g. 0xFFFF/0xA = 0x1999 
// would allow 1 point decimal result coordinate. 
// See in PDF specification: 8.9.5.2 Decode Arrays 
decodeArray.add(COSInteger.ZERO); 
decodeArray.add(COSInteger.get(0xFFFF)); 
decodeArray.add(COSInteger.ZERO); 
decodeArray.add(COSInteger.get(0xFFFF)); 
// colors r g b map 8 bits from 0..FF to 0..1 
decodeArray.add(COSInteger.ZERO); 
decodeArray.add(COSInteger.ONE); 
decodeArray.add(COSInteger.ZERO); 
decodeArray.add(COSInteger.ONE); 
decodeArray.add(COSInteger.ZERO); 
decodeArray.add(COSInteger.ONE); 
gouraudShading.setDecodeValues(decodeArray); 
gouraudShading.setColorSpace(PDDeviceRGB.INSTANCE); 

// Function is not required for type 4 shadings and not really useful, 
// because if a function would be used, each edge "color" of a triangle would be one value, 
// which would then transformed into n color components by the function so it is 
// difficult to get 3 "extremes". 

OutputStream os = ((COSStream) gouraudShading.getCOSObject()).createOutputStream(); 
MemoryCacheImageOutputStream mcos = new MemoryCacheImageOutputStream(os); 

// Vertex 1, starts with flag1 
// (flags always 0 for vertices of start triangle) 
mcos.writeByte(0); 
// x1 y1 (left corner) 
mcos.writeShort(0); 
mcos.writeShort(0); 
// r1 g1 b1 (red) 
mcos.writeByte(0xFF); 
mcos.writeByte(0); 
mcos.writeByte(0); 

// Vertex 2, starts with flag2 
mcos.writeByte(0); 
// x2 y2 (top corner) 
mcos.writeShort(100); 
mcos.writeShort(100); 
// r2 g2 b2 (green) 
mcos.writeByte(0); 
mcos.writeByte(0xFF); 
mcos.writeByte(0); 

// Vertex 3, starts with flag3 
mcos.writeByte(0); 
// x3 y3 (right corner) 
mcos.writeShort(200); 
mcos.writeShort(0); 
// r3 g3 b3 (blue) 
mcos.writeByte(0); 
mcos.writeByte(0); 
mcos.writeByte(0xFF); 

mcos.close(); 
// outside stream MUST be closed as well, see javadoc of MemoryCacheImageOutputStream 
os.close(); 

이 음영을 실행하기를

contentStream.shadingFill(gouraudShading); 

Gouraud shaded triangle

여기에 다른 디코드 배열이 있습니다. 나는 24의 16 비트 대신 사용하지만 당신이 링크 예를 들어, PDF에서 하나 :

COSArray decodeArray = new COSArray(); 
// coordinates x y map 16 bits 0..FFFF to -16384..16384 
// this means that 0x8000 maps to 0 
// some other useful values 
// - 0x862C maps to top of A4 page 
// - 0x84C4 maps to right of A4 page 
// - 0x8262 maps to horizontal middle of A4 page 
decodeArray.add(COSInteger.get(-16384)); 
decodeArray.add(COSInteger.get(16384)); 
decodeArray.add(COSInteger.get(-16384)); 
decodeArray.add(COSInteger.get(16384)); 
// colors r g b map 8 bits from 0..FF to 0..1 
decodeArray.add(COSInteger.ZERO); 
decodeArray.add(COSInteger.ONE); 
decodeArray.add(COSInteger.ZERO); 
decodeArray.add(COSInteger.ONE); 
decodeArray.add(COSInteger.ZERO); 
decodeArray.add(COSInteger.ONE); 
gouraudShading.setDecodeValues(decodeArray); 

삼각형의 좌표는 0x8000이 0x8000을, 0x8100 0x8100, 0x8200 0x8000이 될 것입니다.

+0

고마워요. 선생님, 큰 도움이되었습니다. – user3194123