Просматривать весь PDF и удалять только подчеркивания гиперссылок (аннотации) + iText - PullRequest
0 голосов
/ 20 сентября 2019

Я успешно изменил цвет подчеркивания, используя код ссылки ниже.Может кто-нибудь помочь мне, как удалить подчеркивания из PDF, подчеркивания, которые я нашел, используя код ссылки ниже.

Пройдите по всему PDF и измените синий цвет на черный (также измените цвет подчеркивания) + iText

Ниже приведен мой код, который находит гиперссылки и меняет цвет на черный.Я должен изменить этот код, чтобы удалить эти подчеркивания.

PdfCanvasEditor editor = new PdfCanvasEditor() {
    @Override
    protected void write(PdfCanvasProcessor processor, PdfLiteral operator, List<PdfObject> operands)
    {
        String operatorString = operator.toString();

        if (SET_FILL_RGB.equals(operatorString) && operands.size() == 4) {
            if (isApproximatelyEqual(operands.get(0), 0) &&
                    isApproximatelyEqual(operands.get(1), 0) &&
                    isApproximatelyEqual(operands.get(2), 1)) {
                super.write(processor, new PdfLiteral("g"), Arrays.asList(new PdfNumber(0), new PdfLiteral("g")));
                return;
            }
        }

        if (SET_STROKE_RGB.equals(operatorString) && operands.size() == 4) {
            if (isApproximatelyEqual(operands.get(0), 0) &&
                    isApproximatelyEqual(operands.get(1), 0) &&
                    isApproximatelyEqual(operands.get(2), 1)) {
                super.write(processor, new PdfLiteral("G"), Arrays.asList(new PdfNumber(0), new PdfLiteral("G")));
                return;
            }
        }

        super.write(processor, operator, operands);
    }

    boolean isApproximatelyEqual(PdfObject number, float reference) {
        return number instanceof PdfNumber && Math.abs(reference - ((PdfNumber)number).floatValue()) < 0.01f;
    }

    final String SET_FILL_RGB = "rg";
    final String SET_STROKE_RGB = "RG";
};
for (int i = 1; i <= pdfDocument.getNumberOfPages(); i++) {
    editor.editPage(pdfDocument, i);
}

Отредактировано:

Принятый ответ не работает для следующих файлов:

https://raad -dev-test.s3.ap-south-1.amazonaws.com/36/2019-08-30/021549Orig1s025_aprepitant_clinpharm_prea_Mac.pdf (стр. 41)

https://raad -dev-test.s3.ap-south-1.amazonaws.com / 36 / 2019-08-30 / 400_206494S5_avibactam_and_ceftazidine_unireview_prea_Mac.pdf (стр. 60).

Пожалуйста, помогите.

1 Ответ

1 голос
/ 21 сентября 2019

Как описано в комментарии в контексте упомянутого вопроса

, легко сделать приведенный выше класс редактора удаляющим векторную графику, заменяя инструкции заливки или обводки инструкциями, отбрасывающими текущий путь без рисованияЭто.Если это произойдет только в том случае, если применимый текущий цвет будет синим, это, вероятно, сработает в случае ваших примеров PDF-файлов.Но имейте в виду, что в документах с другой графикой с синими элементами (например, логотипами) они также могут быть искажены. ( RemoveGraphicsByColor вспомогательный класс)

Применяется так:

try (   PdfReader pdfReader = new PdfReader(INPUT);
        PdfWriter pdfWriter = new PdfWriter(OUTPUT);
        PdfDocument pdfDocument = new PdfDocument(pdfReader, pdfWriter) )
{
    PdfCanvasEditor editor = new PdfGraphicsRemoverByColor(ColorConstants.BLUE);
    for (int i = 1; i <= pdfDocument.getNumberOfPages(); i++)
    {
        editor.editPage(pdfDocument, i);
    }
}

( RemoveGraphicsByColor тесты)

к файлам примеров Control_of_nitrosamine_impurities_in_sartans__rev.pdf, EDQM_reports_issues_of_non-compliance_with_tooth__Mac.pdf и originalFile.pdf из указанного вопроса можно получить:

Control_of_nitrosamine_impurities_in_sartans__rev.pdf

и

EDQM_reports_issues_of_non-compliance_with_tooth__Mac.pdf

и

originalFile.pdf

Осторожно, этоэто просто подтверждение концепции, а не окончательное и полное решение.В частности:

  • Рассматривается только синий RGB.Это может быть проблемой, особенно в случае документов, специально предназначенных для печати (вероятно, с использованием цветов CMYK).

  • Все заливки и обводки пути удаляются, пока они синего цвета.В зависимости от ваших документов это может быть отфильтровано.

  • PdfCanvasEditor только проверяет и редактирует поток содержимого самой страницы, а не потоки содержимого отображаемых форм XObjects или шаблонов;таким образом, некоторый контент может быть не найден.Его можно довольно легко обобщить.

Отличающиеся оттенки синего от других цветовых пространств RGB'ов

Тестируя приведенный выше код, вы обнаружили документы, в которых синие линии неудален.Как оказалось, эти синие цвета были не из стандартного RGB DeviceRGB , а вместо цветовых пространств ICCBased , а точнее профилированных цветовых пространств RGB.Кроме того, в одном документе был использован не просто синий 0 0 1, а вместо .17255 .3098 .63529 синий.

Чтобы также иметь возможность работать с этими документами, подход выше должен быть обобщен;например, мы можем использовать Predicate<Color> вместо одного конкретного Color, например, вот так:

class PdfGraphicsRemoverByColorPredicate extends PdfCanvasEditor {
    public PdfGraphicsRemoverByColorPredicate(Predicate<Color> colorPredicate) {
        this.colorPredicate = colorPredicate;
    }

    @Override
    protected void write(PdfCanvasProcessor processor, PdfLiteral operator, List<PdfObject> operands)
    {
        String operatorString = operator.toString();

        if (colorPredicate.test(getGraphicsState().getFillColor())) {
            switch (operatorString) {
            case "f":
            case "f*":
            case "F":
                operatorString = "n";
                break;
            case "b":
            case "b*":
                operatorString = "s";
                break;
            case "B":
            case "B*":
                operatorString = "S";
                break;
            }
        }

        if (colorPredicate.test(getGraphicsState().getStrokeColor())) {
            switch (operatorString) {
            case "s":
            case "S":
                operatorString = "n";
                break;
            case "b":
            case "B":
                operatorString = "f";
                break;
            case "b*":
            case "B*":
                operatorString = "f*";
                break;
            }
        }

        operator = new PdfLiteral(operatorString);
        operands.set(operands.size() - 1, operator);
        super.write(processor, operator, operands);
    }

    final Predicate<Color> colorPredicate;
}

( RemoveGraphicsByColor вспомогательный класс)

Применяется так:

try (   PdfReader pdfReader = new PdfReader(INPUT);
        PdfWriter pdfWriter = new PdfWriter(OUTPUT);
        PdfDocument pdfDocument = new PdfDocument(pdfReader, pdfWriter) )
{
    PdfCanvasEditor editor = new PdfGraphicsRemoverByColorPredicate(RemoveGraphicsByColor::isRgbBlue);
    for (int i = 1; i <= pdfDocument.getNumberOfPages(); i++)
    {
        editor.editPage(pdfDocument, i);
    }
}

( RemoveGraphicsByColor testRemoveAllBlueLinesFrom* tests)

к новым файлам примеров с использованием этого предикатаметод

public static boolean isRgbBlue(Color color) {
    if (color instanceof CalRgb || color instanceof DeviceRgb || (color instanceof IccBased && color.getNumberOfComponents() == 3)) {
        float[] components = color.getColorValue();
        float r = components[0];
        float g = components[1];
        float b = components[2];
        return b > .5f && r < .9f*b && g < .9f*b;
    }
    return false;
}

( RemoveGraphicsByColor вспомогательный метод)

один получает

021549Orig1s025_aprepitant_clinpharm_prea_Mac.pdf

и

400_206494S5_avibactam_and_ceftazidine_unireview_prea_Mac.pdf

Остерегайтесь, предупреждения все еще действуют.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...