当前位置: 首页 > 知识库问答 >
问题:

使用PDShadingType4 Apache pdf框实现类型4着色

程阳平
2023-03-14

我一直在尝试使用apache pdf框创建一个pdf格式的三角形。使用PDShadingType4类。下面是代码实现,但它只创建了空的PDF。我在Apache提供的示例中没有找到任何PDShadingType4的实现。

生成的三角形应该类似于pdf的左下方的三角形,在apache pdf box问题中可以找到

我找不到任何使用PDShadingType4的着色示例。

以下执行是否正确?或者是使用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");
        }
    }

共有1个答案

寿亦
2023-03-14

这段代码在左下方创建一个Gouraud阴影三角形:

// 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);

这里有一个不同的解码数组,类似于您链接到的示例PDF中的一个,尽管我使用的是16位而不是24位:

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。

 类似资料:
  • 问题内容: 我有课 和班级 关键是该方法不安全,因为我可以提供的项目与当前报告无关,但与其他报告相关,编译器不会抱怨。 是否可以用类型安全的方式编写该方法,即我们可以仅将T作为当前报表的类型作为参数传递。 问题答案: 我认为您正在寻找以下内容。 它的工作方式是: 您想用从 您要确保所有列表都属于同一类型 为了将参数绑定到从扩展的对象,您需要对自身进行参数化: 您添加需要从报表扩展的绑定 但是您要

  • 本文向大家介绍Vue使用枚举类型实现HTML下拉框步骤详解,包括了Vue使用枚举类型实现HTML下拉框步骤详解的使用技巧和注意事项,需要的朋友参考一下 下拉框包含option中的Value和用来显示的选项, 一般后台都是使用的Value值,而不是显示在前台的选项 第一步: 编写下拉框需要的枚举类型   StatusEnum.java 第二步: 编写用来存放下拉框中对应的option中的Value和

  • 本文向大家介绍使用vue实现各类弹出框组件,包括了使用vue实现各类弹出框组件的使用技巧和注意事项,需要的朋友参考一下 简单介绍一下vue中常用dialog组件的封装: 实现动态传入内容,实现取消,确认等回调函数。 首先写一个基本的弹窗样式,如上图所示。 在需要用到弹窗的地方中引入组件: 点击一个按钮显示弹窗,并保证关闭弹窗后再次点击依旧显示 在弹窗组件中定义一个value值:v-model="s

  • 好吧,乖点。 这里有一个枚举,它实现了一个接口,该接口返回一个“原始类型”,它给我一个关于接口中的方法的警告。 如果我将接口的方法更改为: 它会在的方法签名上变为未经检查的警告。如果我改变的签名: 然后返回有一个不兼容的类型错误,因为

  • 本文向大家介绍Bootstrap 4 .d-flex类的实现,包括了Bootstrap 4 .d-flex类的实现的使用技巧和注意事项,需要的朋友参考一下 在Bootstrap中使用d-flex类创建一个flexbox容器。 在这里,我设置了两个flex项目- 您可以尝试运行以下代码来实现.d-flex类- 示例

  • 我正在尝试一个非常基本(人为)的条件类型函数,但遇到了意外错误: 我认为这是一个非常简单的条件类型用法,所以不确定发生了什么。有什么想法吗?