Как вы уже узнали сами, причина вывода 0x0 заключается в том, что код из PrintImageLocations
как есть вообще не может найти изображение.
PrintImageLocations
не находит изображение, потому чтоон ищет только изображения, используемые в содержимом страницы и в форме XObjects (также вложенных), используемых в содержимом страницы.С другой стороны, в данном файле изображение рисуется внутри мозаичного содержимого Pattern , которое используется для заполнения области содержимого страницы.
Чтобы PDFBox мог найти это изображение, нам нужно немного расширить класс PrintImageLocations
, чтобы также спускаться в потоки содержимого шаблона, например, так:
class PrintImageLocationsImproved extends PrintImageLocations {
public PrintImageLocationsImproved() throws IOException {
super();
addOperator(new SetNonStrokingColor());
addOperator(new SetNonStrokingColorN());
addOperator(new SetNonStrokingDeviceCMYKColor());
addOperator(new SetNonStrokingDeviceGrayColor());
addOperator(new SetNonStrokingDeviceRGBColor());
addOperator(new SetNonStrokingColorSpace());
}
@Override
protected void processOperator(Operator operator, List<COSBase> operands) throws IOException {
String operation = operator.getName();
if (fillOperations.contains(operation)) {
PDColor color = getGraphicsState().getNonStrokingColor();
PDAbstractPattern pattern = getResources().getPattern(color.getPatternName());
if (pattern instanceof PDTilingPattern) {
processTilingPattern((PDTilingPattern) pattern, null, null);
}
}
super.processOperator(operator, operands);
}
final List<String> fillOperations = Arrays.asList("f", "F", "f*", "b", "b*", "B", "B*");
}
( ExtractImageLocations внутренний класс PrintImageLocationsImproved
)
Шаблон мозаики в документе, который используется, используется в качестве цвета шаблона для заливки, а не штриховки.Таким образом, PrintImageLocationsImproved
должен зарегистрировать прослушиватели операторов для цветных операторов без штрихов, чтобы правильно обновить цвет заливки в графическом состоянии.
processOperator
перед делегированием реализации PrintImageLocations
теперь сначала проверяет, является лиоператором является операция fill .В этом случае он проверяет текущий цвет заливки.Если это цвет шаблона, processOperator
инициирует обработку processTilingPattern
, определенную в PDFStreamEngine
, которая запускает вложенный анализ потока содержимого шаблона и, таким образом, в конечном итоге позволяет PrintImageLocationsImproved
найти изображение.
ИспользованиеPrintImageLocationsImproved
вот так
try ( PDDocument document = PDDocument.load(...) )
{
PrintImageLocations printer = new PrintImageLocationsImproved();
int pageNum = 0;
for( PDPage page : document.getPages() )
{
pageNum++;
System.out.println( "Processing page: " + pageNum );
printer.processPage(page);
}
}
( ExtractImageLocations test testExtractLikeHelloWorldImprovedFromTopSecret
)
для вашего PDF-файла, поэтому найдет изображение:
Processing page: 1
*******************************************************************
Found image [R8]
position in PDF = 39.0, 102.48 in user space units
raw image size = 1209, 1640 in pixels
displayed size = 516.3119, 700.3752 in user space units
displayed size = 7.1709986, 9.727433 in inches at 72 dpi rendering
displayed size = 182.14336, 247.0768 in millimeters at 72 dpi rendering
Осторожно,
это не идеальное исправление, скорее подтверждение концепции и обходной путь, так как он не ограничивает шаблон должным образом заполненной областью.и не возвращать множественные находки для области, достаточно большой, чтобы заполнить несколько мозаичных плиток.Тем не менее, он возвращает изображение соответствия для файла под рукой ..