2017-05-03 11 views
0

私は、pdfのapache pdfボックスを使用してpdfで三角形を作成しようとしています。 PDShadingType4クラスを使用しています。以下はコードの実装ですが、空のpdfしか作成しませんでした。私はapacheで提供されているPDShadingType4の実装が見つかりませんでした。PDShadingType4 Apacheを使用してタイプ4のシェーディングを実装するpdf box

生成された三角形は、私がPDShadingType4を使用して、任意のシェーディングの例を見つけることができないのですapacheの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(ラジアル)ではありませんか?これらの2つはPDFBoxのソースコードに例があり、タイプ4のシェーディングは難しいので、タイプ4のシェーディングはあなたが言及したような三角です。通常、3Dの錯覚を作成するには、それらのトンがあります。あなたのコードはストリームを見逃しています。 PDF仕様を参照してください。色、座標、フラグが含まれています。非常にトリッキーなもの。 –

+0

あなたはまた、機能のものを必要としません、それは必須ではありません、あなたはそれを使用しないでよりカラフルな三角形を得ることができます。 (関数を使用している場合、三角形の各辺は1つの値になり、関数によってn個の色成分に変換され、3つの極値を得ることは困難です)。ストリームの内容は、f x y c1 ... cnです(仕様のp190を参照)。あなたが本当に必要と思っているのであればデモを実装することができます。 –

+0

はい私はタイプ4のシェーディングが必要です。あなたが作成したリンクであなたの言葉通りにPDF仕様を読んだ後にタイプ4のシェーディングも試みました。しかし、複雑になっています。リンクやドキュメントを見つけることができませんでした三角形のあなたは上記のコードを修正してください、またはあなたが作成した三角形のコードへのリンクを提供してください。私には非常に便利です。私たちは、タイプ2(軸)またはタイプ3(放射状)シェーディング。この後、ポリゴンを描く必要があります。タイプ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

ここには別のデコード配列があります

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を次のようになります。たとえば、PDFから1あなたは、私が唯一の16ビットの代わりに24を使用しましたが、にリンクしています。

+0

ありがとう、それは大きな助けとなった。 – user3194123

関連する問題