Есть ли способ удалить только QR-коды с каждой страницы PDF с помощью iText7?

Вопрос или проблема

Я пытаюсь удалить QR-код с каждой страницы, используя iText7, но это искажает все остальные текстовые значения и компоненты страницы. Есть ли способ сделать это правильно? Ниже приведен код, который я использую:

ЦиклНачало{

        PdfPage page = pdfDoc.getPage(i);
        PdfDictionary resources = page.getResources().getPdfObject();

        // Извлечь все объекты изображений на странице
        PdfDictionary xObjects = resources.getAsDictionary(PdfName.XObject);
        если (xObjects != null) {
            для (PdfName name : xObjects.keySet()) {
                PdfObject obj = xObjects.get(name);
                если (obj instanceof PdfStream) {
                    PdfStream stream = (PdfStream) obj;
                    PdfImageXObject image = new PdfImageXObject(stream);

                    // Получить ширину и высоту из словаря изображения
                    float width = image.getWidth();
                    float height = image.getHeight();

                    // Проверить, соответствуют ли размеры изображения типичному QR-коду
                    если (isLikelyQRCode(width, height)) {
                        // Очистить содержимое изображения, чтобы эффективно удалить его
                        stream.clear();
                    }
                }
            }
        }
    
ЦиклКонец}


// Метод для определения, соответствует ли изображение типичному размеру QR-кода
`private static boolean isLikelyQRCode(float width, float height) {
    // QR-коды обычно квадратные или почти квадратные
    вернуть width >= 50f && width <= 200f &&
           height >= 50f && height <= 200f &&
           Math.abs(width - height) < 10; 
}`

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

Ответ или решение

Вопрос избавления от QR-кодов в PDF-файлах с использованием iText7 поднимает ряд технико-технологических нюансов, которые необходимо учитывать для достижения максимального результата без ущерба для остального содержимого документа. Ваши текущие подходы, основанные на очистке данных потока изображения, могут приводить к искажению других элементов страницы, что является распространенной проблемой при работе с PDF.

Анализ и решение

  1. Анализ текущего кода:

    • Ваша реализация проходит по страницам PDF, извлекает объекты XObject, и проверяет все изображения на соответствие заданному размеру для QR-кодов. Однако, при очистке содержимого потока изображения с помощью stream.clear();, вы потенциально нарушаете другие элементы, зависящие от данного изображения.
  2. Улучшение детекции:

    • Вместо определения размеров изображения, можно использовать более продвинутый подход, например, распознавание QR-кодов. Для этого можно интегрировать библиотеку для распознавания QR-кодов и при нахождении подходящего изображения удалять только его.
  3. Метод удаления:

    • Вместо очистки содержимого изображения, которое может вызвать искажения, лучше удалить сам объект XObject. Это позволит устранить только QR-коды без вреда для остальных компонентов страницы.

Рекомендованное решение

Вот переработанный подход, позволяющий удалять QR-коды, сохраняя целостность остальных элементов PDF-документа:

import com.itextpdf.kernel.pdf.*;
import com.itextpdf.kernel.pdf.canvas.parser.*;
import com.itextpdf.kernel.pdf.canvas.parser.listener.ImageRenderInfo;

PdfDocument pdfDoc = new PdfDocument(new PdfReader("input.pdf"), new PdfWriter("output.pdf"));

for (int i = 1; i <= pdfDoc.getNumberOfPages(); i++) {
    PdfPage page = pdfDoc.getPage(i);
    PdfDictionary resources = page.getResources().getPdfObject();

    if (resources != null) {
        PdfDictionary xObjects = resources.getAsDictionary(PdfName.XObject);
        if (xObjects != null) {
            for (PdfName name : xObjects.keySet()) {
                PdfObject obj = xObjects.get(name);
                if (obj instanceof PdfStream) {
                    PdfImageXObject image = new PdfImageXObject((PdfStream) obj);

                    // Здесь добавляется ваша логика распознавания QR-кодов
                    if (isQRCode(image)) {
                        // Удаляем объект изображения
                        xObjects.remove(name);
                    }
                }
            }
        }
    }
}

pdfDoc.close();

Метод для распознавания QR-кодов

Для реализации метода isQRCode, можно использовать библиотеку, такую как ZXing или другую библиотеку для распознавания QR-кодов. Пример кода будет выглядеть так:

private static boolean isQRCode(PdfImageXObject image) {
    // Преобразуем изображение в массив байт
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    image.getImageAsBytes(baos);

    // Используем библиотеку для распознавания QR-кодов
    // Пример с ZXing (добавьте зависимости в проект)
    BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(new BitmapSource( baos.toByteArray() )));
    try {
        Result result = new MultiFormatReader().decode(bitmap);
        return result.getBarcodeFormat() == BarcodeFormat.QR_CODE;
    } catch (NotFoundException e) {
        return false;
    }
}

Заключение

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

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

Оцените материал
Добавить комментарий

Капча загружается...