Как получить цвет шрифта с помощью pdfbox


Я пытаюсь извлечь текст со всей информацией из pdf с помощью pdfbox. Я получил всю необходимую информацию, кроме цвета. Я пробовал разные способы получить fontcolor (включая Получение цвета текста с помощью PDFBox ). Но не работает. А теперь я скопировал код из класса PageDrawer pdfBox. Но тогда и значение RGB не является правильным.

protected void processTextPosition(TextPosition text) {

        Composite com;
        Color col;
        switch(this.getGraphicsState().getTextState().getRenderingMode()) {
        case PDTextState.RENDERING_MODE_FILL_TEXT:
            com = this.getGraphicsState().getNonStrokeJavaComposite();
            int r =       this.getGraphicsState().getNonStrokingColor().getJavaColor().getRed();
            int g = this.getGraphicsState().getNonStrokingColor().getJavaColor().getGreen();
            int b = this.getGraphicsState().getNonStrokingColor().getJavaColor().getBlue();
            int rgb = this.getGraphicsState().getNonStrokingColor().getJavaColor().getRGB();
            float []cosp = this.getGraphicsState().getNonStrokingColor().getColorSpaceValue();
            PDColorSpace pd = this.getGraphicsState().getNonStrokingColor().getColorSpace();
            break;
        case PDTextState.RENDERING_MODE_STROKE_TEXT:
            System.out.println(this.getGraphicsState().getStrokeJavaComposite().toString());
            System.out.println(this.getGraphicsState().getStrokingColor().getJavaColor().getRGB());
           break;
        case PDTextState.RENDERING_MODE_NEITHER_FILL_NOR_STROKE_TEXT:
            //basic support for text rendering mode "invisible"
            Color nsc = this.getGraphicsState().getStrokingColor().getJavaColor();
            float[] components = {Color.black.getRed(),Color.black.getGreen(),Color.black.getBlue()};
            Color  c1 = new Color(nsc.getColorSpace(),components,0f);
            System.out.println(this.getGraphicsState().getStrokeJavaComposite().toString());
            break;
        default:
            System.out.println(this.getGraphicsState().getNonStrokeJavaComposite().toString());
            System.out.println(this.getGraphicsState().getNonStrokingColor().getJavaColor().getRGB());
    }

Я использую приведенный выше код. Получаемые значения являются r = 0, g = 0, b = 0, внутри объекта cosp значение равно [0.0], внутри массива объектов pd = null и colorSpace = null. а значение RGB всегда равно -16777216. Пожалуйста, помогите мне. Заранее спасибо.

4 7

4 ответа:

Я попробовал код в ссылке, которую вы разместили, и он сработал для меня. Цвета, которые я получаю обратно, - 148,92, 179,01001 и 214,965. Я хотел бы дать вам мой PDF для работы, может быть, если я сохраню его внешне, чтобы так? Мой PDF использовал какой-то бледно-голубой цвет, и это, кажется, соответствует. Это была всего лишь одна страница текста, созданного в Word 2010 и экспортированного, ничего слишком интенсивного.

Несколько предложений ....

  1. Напомним, что возвращаемое значение является плавающим между 0 и 1. Если значение равно случайно приведите к int, тогда, конечно, значения будут содержать почти все 0. Связанное с кодом умножается на 255, чтобы получить диапазон от 0 до 255.
  2. Как сказал комментатор, наиболее распространенным цветом для PDF-файла является черный, который равен 0 0 0

Это все, что я могу сейчас придумать, в противном случае у меня есть версия 1.7.1 pdfbox и fontbox, и, как я уже сказал, я в значительной степени следовал ссылке, которую вы дали.

EDIT

Основываясь на моих комментариях, здесь, возможно, есть малоинвазивный способ сделать это для pdf-файлов, таких как color.pdf?

В PDFStreamEngine.java в методе processOperator можно сделать внутри блока try

if (operation.equals("RG")) {
   // stroking color space
   System.out.println(operation);
   System.out.println(arguments);
} else if (operation.equals("rg")) {
   // non-stroking color space
   System.out.println(operation);
   System.out.println(arguments);
} else if (operation.equals("BT")) {
   System.out.println(operation);    
} else if (operation.equals("ET")) {
   System.out.println(operation);           
}
Это покажет вам информацию, затем вы должны обработать информацию о цвете для каждого раздела В соответствии с вашими потребностями. Вот фрагмент из начала вывода приведенного выше кода при запуске на color.pdf ...

BT rG [COSInt(1), COSInt(0), CosInt(0)] RG [COSInt(1), COSInt(0), CosInt(0)] ET BT ET BT rG [COSFloat{0.573}, COSFloat{0.816}, COSFloat{0.314}] RG [COSFloat{0.573}, COSFloat{0.816}, COSFloat{0.314}] ET ......

Вы видите в приведенном выше выводе пустой раздел BT ET, это раздел, который помечен DEVICEGRAY. Все остальные дают вам [0,1] значения для компонентов R, G и B

Я также закончил делать что-то вроде этого. Вставляя код ниже, надеюсь, что это кому-то поможет.

import java.io.IOException;
import java.util.List;
import org.apache.pdfbox.exceptions.COSVisitorException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.edit.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.graphics.PDGraphicsState;
import org.apache.pdfbox.util.PDFTextStripper;
import org.apache.pdfbox.util.ResourceLoader;
import org.apache.pdfbox.util.TextPosition;

public class Parser extends PDFTextStripper {

public Parser() throws IOException {
    super(ResourceLoader.loadProperties(
            "org/apache/pdfbox/resources/PageDrawer.properties", true));
    super.setSortByPosition(true);
}

public void parse(String path) throws IOException{
    PDDocument doc = PDDocument.load(path);
    List<PDPage> pages = doc.getDocumentCatalog().getAllPages();
    for (PDPage page : pages) {
        this.processStream(page, page.getResources(), page.getContents().getStream());
    }
}

@Override
protected void processTextPosition(TextPosition text) {
    try {
        PDGraphicsState graphicsState = getGraphicsState();
        System.out.println("R = " + graphicsState.getNonStrokingColor().getJavaColor().getRed());
        System.out.println("G = " + graphicsState.getNonStrokingColor().getJavaColor().getGreen());
        System.out.println("B = " + graphicsState.getNonStrokingColor().getJavaColor().getBlue());
    }
    catch (IOException ioe) {}

}

public static void main(String[] args) throws IOException, COSVisitorException {
    Parser p = new Parser();
    p.parse("/Users/apple/Desktop/123.pdf");
}

}

Я нашел какой-то код в одной из моих программ технического обслуживания.
Я не знаю, работает это для вас или нет, пожалуйста, попробуйте. Также проверьте эту ссылку http://pdfbox.apache.org/apidocs/org/apache/pdfbox/pdmodel/common/class-use/PDStream.html

Это может помочь вам

PDDocument doc = null;
try {
    doc = PDDocument.load("C:/Path/To/Pdf/Sample.pdf");
    PDFStreamEngine engine = new PDFStreamEngine(ResourceLoader.loadProperties("org/apache/pdfbox/resources/PageDrawer.properties"));
    PDPage page = (PDPage)doc.getDocumentCatalog().getAllPages().get(0);
    engine.processStream(page, page.findResources(), page.getContents().getStream());
    PDGraphicsState graphicState = engine.getGraphicsState();
    System.out.println(graphicState.getStrokingColor().getColorSpace().getName());
    float colorSpaceValues[] = graphicState.getStrokingColor().getColorSpaceValue();
    for (float c : colorSpaceValues) {
        System.out.println(c * 255);
    }
}
finally {
    if (doc != null) {
        doc.close();
    }

С pdfbox verson 2.0+ необходимо выбрать эти операторы в конструкторе вашего перезаписанного PDFTextStripper:

addOperator(new SetStrokingColorSpace());
addOperator(new SetNonStrokingColorSpace());
addOperator(new SetStrokingDeviceCMYKColor());
addOperator(new SetNonStrokingDeviceCMYKColor());
addOperator(new SetNonStrokingDeviceRGBColor());
addOperator(new SetStrokingDeviceRGBColor());
addOperator(new SetNonStrokingDeviceGrayColor());
addOperator(new SetStrokingDeviceGrayColor());
addOperator(new SetStrokingColor());
addOperator(new SetStrokingColorN());
addOperator(new SetNonStrokingColor());
addOperator(new SetNonStrokingColorN());

Только тогда getGraphicsState () вернет соответствующую информацию.

См. https://pdfbox.apache.org/2.0/migration.html