Как создать двухмерный штрихкод в виде векторного изображения?

91
27 февраля 2021, 15:20

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

BarcodePDF417 pdf417 = new BarcodePDF417();
String text = "BarcodePDF417 barcode";
pdf417.setText(text);
Image img = pdf417.getImage();        
document.add(img);

Мы берем метод placeBarcode() для создания векторного изображения. Мы попытались использовать его следующим образом:

Rectangle pageSize = new Rectangle(w * 72, h * 72);
Document doc = new Document(pageSize, 1f, 1f, 1f, 1f);
PdfWriter writer = PdfWriter.getInstance(doc, getOutputStream());
doc.open();
PdfContentByte cb = writer.getDirectContent();
BarcodePDF417 pf = new BarcodePDF417();
pf.setText("BarcodePDF417 barcode");
Rectangle rc = pf.getBarcodeSize();
pf.placeBarcode(cb, BaseColor.BLACK, rc.getHeight(), rc.getWidth());
doc.close();

В результате страница становится полностью черной

Answer 1

Посмотрите пример BarcodePlacement. Здесь мы создаем три штрихкода PDF417:

Image img = createBarcode(1, 1, pdfDoc); 
doc.add(new Paragraph(String.format("This barcode measures %s by %s user units", 
    img.getImageScaledWidth(), img.getImageScaledHeight()))); 
doc.add(img); 
img = createBarcode(3, 3, pdfDoc); 
doc.add(new Paragraph(String.format("This barcode measures %s by %s user units", 
    img.getImageScaledWidth(), img.getImageScaledHeight()))); 
doc.add(img); 
img = createBarcode(3, 1, pdfDoc); 
doc.add(new Paragraph(String.format("This barcode measures %s by %s user units", 
    img.getImageScaledWidth(), img.getImageScaledHeight()))); 
doc.add(img);

Результат выглядит следующим образом:

Штрихкоды

Так выглядит один из штрихкодов внутри:

Векторные данные

Я добавляю вид изнутри, чтобы показать, что двухмерный штрихкод не добавляется как растровое изображение (как в вашем примере). Это векторное изображение, состоящее из группы маленьких прямоугольников. Вы можете проверить это самостоятельно в файле barcode_placement.pdf. Объект Image не должен вас запутать. Если вы посмотрите на метод createBarcode(), то увидите, что Image в действительности является векторным изображением:

public Image createBarcode(float mw, float mh, PdfDocument pdfDoc) { 
    BarcodePDF417 barcode = new BarcodePDF417(); 
    barcode.setCode("BarcodePDF417 barcode"); 
    return new Image(barcode.createFormXObject(Color.BLACK, pdfDoc)).scale(mw, mh); 
}

Высота и ширина, которые передаются через метод scale(), определяют высоту и ширину маленьких прямоугольников. Во внутренней части штрихкода, можно увидеть следующее:

0 21 3 1 re

Это прямоугольник, у которого x = 0, y = 21, ширина — 3, а высота —1. Когда вы запрашиваете размер штрихкода, то получаете число необходимых прямоугольников. Размеры штрихкода будут рассчитываться следующим образом:

Rectangle size = barcode.getBarcodeSize(); 
float width = mw * size.getWidth(); 
float height = mh * size.getHeight();

Вы допускаете, что значение size (размер в единицах пользователя) верно, только если mw и mh равняются 1. Я использую значения для создания примера PdfFormXObject и переношу его в Image. Затем я могу добавить Image к документу, как и любое другое изображение. Основное отличие этого изображения от обычных заключается в том, что оно векторное.

READ ALSO
Как вытащить определенное значение из map

Как вытащить определенное значение из map

Есть класс Person, он имеет три поля - name, age и surnameЯ создаю HashMap из Person'ов и хочу вытащить все surname записать в отдельный лист

162
Непонятный класс EntrySet

Непонятный класс EntrySet

В java создаю такую конструкциюПо документации метод entrySet возвращает объект типа Set, но под отладчиком что-то непонятное

97
Переход во вторую activity

Переход во вторую activity

Данное приложение сканирует штрих и qr код, как сделать так, чтобы после сканирования, результат сканирования выводился во второй Activity?

99
Вывод окна ожидания

Вывод окна ожидания

Хочу вывести Alert окно, которое будет закрываться после того как выполнится задача из другого класса

130