Может ли кто-нибудь помочь мне, как отличить цвет фона от цвета текста PDF-документа, если цвет фона и цвет текста одинаковы.
На самом деле мне нужно установить статический цвет для невидимого текста. используя pdfbox, чтобы мы могли видеть невидимый текст.
TextObjectInfo содержит всю информацию о текстовых объектах с использованием PDFStreamEngine.
public class SimplePdfRegeneretor {
private PDDocument _document;
private PDResources _pageResource;
private PDFTextObjectInfoExtraction _PDFTextObjectInfoExtraction;
private List<List<TextObjectInfo>> _documentTextObjectInfo;
private void RecreatePDF() throws IOException{
int _pageNo = 0;
for (PDPage page : _document.getPages())
{
List<TextObjectInfo> _pageTextObjectInfo = this._documentTextObjectInfo.get(_pageNo);
try (PDPageContentStream contentStream = new PDPageContentStream(_document,
page, AppendMode.APPEND, false, true)){
Integer _textObjInfoInx = 0 ;
//contentStream.setNonStrokingColor(0,0,0,0);
for(TextObjectInfo _textObjInfo : _pageTextObjectInfo){
Float _xmin = _textObjInfo.get_xyminmax().get(0);
Float _ymin = _textObjInfo.get_xyminmax().get(1);
putTextOnDocument(contentStream,_textObjInfo,_textObjInfo.TextFontObject,_xmin,_ymin,_textObjInfoInx);
_textObjInfoInx++;
}
}
_pageNo++;
}
_pageNo = 0;
for (PDPage _page : _document.getPages())
{
List<Object> newTokens = addTjStringtoContenStream(_page,_pageNo);
PDStream newContents = new PDStream(_document);
writeTokensToStream(newContents, newTokens);
_page.setContents(newContents);
System.out.println("Page TextObject Writting Completed.."+_pageNo);
_pageNo++;
}
}
private void putTextOnDocument(PDPageContentStream contentStream, TextObjectInfo _textObjInfo, PDFont font, Float horizontalPixel,
Float verticalPixel, int TextObjectIndex) throws IOException {
String _textobjstr = "TextObjectIndex-" + TextObjectIndex;
Matrix _tm = _textObjInfo.textMatrixs.get(_textObjInfo.textMatrixs.size()-1);
int fontSize = _textObjInfo.TextFontSize.intValue();
PDGraphicsState _GraphicsState = _textObjInfo.getGraphicsState();
PDTextState _TextState = _GraphicsState.getTextState();
contentStream.beginText();
contentStream.setNonStrokingColor(_GraphicsState.getNonStrokingColor());
contentStream.setStrokingColor(_GraphicsState.getStrokingColor());
contentStream.setRenderingMode(_TextState.getRenderingMode());
contentStream.setFont(font, fontSize);
contentStream.setTextMatrix(_tm);
contentStream.beginMarkedContent(COSName.getPDFName(_textobjstr));
contentStream.endMarkedContent();
contentStream.endText();
}
private List<Object> addTjStringtoContenStream(PDContentStream contentStream, int _pgInx) throws IOException{
PDFStreamParser parser = new PDFStreamParser(contentStream);
Object token = parser.parseNextToken();
List<Object> newTokens = new ArrayList<>();
List<TextObjectInfo> _pageTextObjInfo = this._documentTextObjectInfo.get(_pgInx);
System.out.println("Len of _pageTextObjInfo: "+_pageTextObjInfo.size());
//newTokens.add(Operator.getOperator("q"));
while (token != null)
{
if (token instanceof Operator)
{
Operator op = (Operator) token;
String opName = op.getName();
if (OperatorName.BEGIN_MARKED_CONTENT.equals(opName))
{
// remove the argument to this operator
//System.out.println(newTokens.get(newTokens.size() - 1));
Integer _tjObjInx = Integer.parseInt(((COSName)newTokens.get(newTokens.size() - 1)).getName().replace("TextObjectIndex-", ""));
TextObjectInfo _TextObjectInfo = _pageTextObjInfo.get(_tjObjInx);
COSString _tjStr = _TextObjectInfo.TjString;
newTokens.remove(newTokens.size() - 1);
newTokens.add(_tjStr);
newTokens.add(Operator.getOperator("Tj"));
token = parser.parseNextToken();
continue;
}
else if (OperatorName.END_MARKED_CONTENT.equals(opName))
{
token = parser.parseNextToken();
continue;
}
}
newTokens.add(token);
token = parser.parseNextToken();
}
//newTokens.add(Operator.getOperator("Q"));
return newTokens;
}
private static void writeTokensToStream(PDStream newContents, List<Object> newTokens) throws IOException
{
try (OutputStream out = newContents.createOutputStream(COSName.FLATE_DECODE))
{
ContentStreamWriter writer = new ContentStreamWriter(out);
writer.writeTokens(newTokens);
}
}
}
1. это фоновое изображение
2.это текст черного цвета без фонового изображения.
3.это входной документ, в котором виден текст.
4. и это вывод, где текст невидим, т.е. серебро
Можете ли вы объяснить, чего именно вы хотите достичь? Насколько я понимаю, вы хотите, чтобы цвет текста был равен цвету фона, чтобы текст не был виден. Но в таком случае, почему бы вам просто не нарисовать текст, используя режим рендеринга «Невидимый»? Это добавит текст в документ (для поиска и копирования и вставки), не будучи видимым.
Привет @mkl, мне нужен результат, похожий на изображение исходного документа. Но в нашем случае текст невидим. Как мне сделать это видимым.
Как насчет рисования всего текста с контуром, цвет которого отличается от цвета заливки?
@mkl, не могли бы вы предложить мне какой-нибудь фрагмент кода на примере.
Хорошо, просто на всякий случай: в качестве входных данных у вас есть документ, в котором есть текст, который невидим, потому что он нарисован тем же цветом, что и его фон (а не, например, потому, что позже он чем-то закрыт или потому что шрифт имеет только пустые глифы или потому, что используется режим рендеринга «невидимый»). Результатом должна быть копия документа, в котором виден этот текст. Ваша первоначальная идея заключалась в том, чтобы каким-то образом проверять для каждого бита текста, отличается ли его цвет от фона, и в противном случае изменить его цвет, чтобы он отличался от фона. И мой подход с видимыми контурами тоже подойдет.
привет @mkl во входном документе виден текст, см. третье изображение для справки. но на выходе (4-е изображение) текст не виден.
Итак, вы хотите объединить какое-нибудь фоновое изображение с каким-нибудь документом переднего плана, чтобы при этом передний план не стал невидимым?
@mkl Нет, мой вопрос прост: я хочу, чтобы невидимый текст (например, серебро) был виден в выходном документе. Итак, как я могу это определить и решить? потому что я попытался установить для текста цвет обводки и не обводки, но результат получился ожидаемый.
Хорошо, входной документ с невидимым текстом (из-за одинакового цвета переднего плана и фона) станет видимым. Есть ли у вас пример документа этого типа для тестирования? (Я могу построить его сам, но в вашем может быть что-то особенное, чего не было бы в моем творении).
привет @KJ, пожалуйста, просмотри этот образец входного документа ( acrobat.adobe.com/link/… ) и образец выходного документа ( acrobat.adobe.com/link/…). Я создал для вашей справки
@KJ, если вы посмотрите на образец входного документа, то обнаружите, что тексты, написанные на нем (т. е. «Это невидимые тексты»), невидимы в выходных образцах документов согласно приведенной выше логике кода. Поэтому я хочу сделать это видимым. Это мой вопрос.
@KJ, спасибо за все, что ты сделал. Но есть ли способ программно обработать все документы, имеющие одинаковые проблемы?
«пожалуйста, просмотрите этот образец входного документа…» — Эти документы сбивают с толку. Выше вы сказали мне, что вашей целью было сделать невидимый текст видимым. Но ваши примеры показывают, что вы делаете видимый текст невидимым, а наоборот...
Привет @mkl, твое первое понимание верно. Я делюсь входным образцом документа, чтобы вы могли сравнить его с выходным образцом документа. Я воссоздал выходной образец документа из входного образца документа с помощью приведенной выше логики кода. но тексты становятся невидимыми в выходном документе. Поэтому я хочу, чтобы выходной образец документа был точно таким же, как входной образец документа.
Один вопрос: почему бы вам не сохранить цвет текста при извлечении текста? Затем вы можете просто применить его снова.
«теперь у меня все работает нормально» — Отлично! Но подсказка для вашего следующего вопроса здесь: из вашего вопроса было неясно, как вы использовали PDFStreamEngine
, в частности, не то, что вы не добавили слушателей, связанных с цветом. Таким образом, всегда добавляйте конкретную информацию о том, как вы извлекаете данные, которые приводят к неверным результатам при их обработке.
На самом деле, я переопределяю следующие методы, например, showFontGlyph() иprocessOperator() PDFStreamEngine, чтобы собирать всю информацию о каждом тексте. Спасибо @mkl, я принял к сведению вашу точку зрения.
Я использую pdfbox версии 2.0+, поэтому я добавил следующие операторы в конструктор моего перезаписанного PDFStreamEngine:
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 специально Часть извлечения текста.
Добавьте фрагмент кода и точный API, который вы используете для pdfbox.