, легко сделать приведенный выше класс редактора удаляющим векторную графику, заменяя инструкции заливки или обводки инструкциями, отбрасывающими текущий путь без рисованияЭто.Если это произойдет только в том случае, если применимый текущий цвет будет синим, это, вероятно, сработает в случае ваших примеров 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
из указанного вопроса можно получить:
и
и
Осторожно, этоэто просто подтверждение концепции, а не окончательное и полное решение.В частности:
Рассматривается только синий 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 вспомогательный метод)
один получает
и
Остерегайтесь, предупреждения все еще действуют.