Пикселизация изображения, сгенерированного PIL

#python #opencv #image-processing #python-imaging-library #qr-code

#python #opencv #обработка изображений #python-imaging-library #qr-код

Вопрос:

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

Изображение увеличенного qr-кода из PDF

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

введите описание изображения здесь

В чем может быть проблема и возможные исправления?

 qr_size_mm = 8
MM2PX_FACTOR = 94.48  # 2400 dpi

def create_code(prefix, number, postfix=None):
    message = prefix   str(number)
    message  = postfix if postfix is not None else ""
    series_qrcode = pyqrcode.create(message, error='H', version=3, mode='binary')
    # print(series_qrcode.get_png_size())
    binary = BytesIO()
    desired_scale = int(qr_size_px / series_qrcode.get_png_size())
    series_qrcode.png(binary, scale=desired_scale, module_color=(0, 0, 0),
                      background=(255, 255, 255), quiet_zone=3)

    tmpIm = Image.open(binary).convert('RGB')
    qr_dim = tmpIm.getbbox()
    # print(qr_dim)
    return tmpIm, qr_dim

qr_size_px = int(qr_size_mm * MM2PX_FACTOR)
# create A4 canvas
paper_width_mm = 210
paper_height_mm = 297
start_offset_mm = 10
start_offset_px = start_offset_mm * MM2PX_FACTOR

canvas_width_px = int(paper_width_mm * MM2PX_FACTOR)
canvas_height_px = int(paper_height_mm * MM2PX_FACTOR)
pil_paper_canvas = Image.new('RGB', (canvas_width_px, canvas_height_px), (255, 255, 255))

# desired pixels for 1200 dpi print
required_resolution_px = 94.48  # 47.244     # 23.622
required_resolution = 2400

print("Page dimension {page_width} {page_height} offset {offset}".format(page_width=canvas_width_px, page_height=canvas_height_px, offset=start_offset_px))
start_range = 10000100000000
for n in range(0, 5):
    print("Generating ", start_range n)
    qr_image, qr_box = create_code("TLTR", number=start_range n)
    # qr_image.show()
    print("qr_box ", qr_box)
    qr_x = int(start_offset_px   ((n 1) * qr_box[2]))
    qr_y = int(start_offset_px)
    print("pasting at ", qr_x, qr_y)
    pil_paper_canvas.paste(qr_image, (qr_x, qr_y))

    # create a canvas just for current qrcode
    one_qr_canvas = Image.new('RGB', (int(10*MM2PX_FACTOR), int(10*MM2PX_FACTOR)), (255, 255, 255))
    qrXY = int((10*MM2PX_FACTOR - qr_box[2]) / 2)
    one_qr_canvas.paste(qr_image, (qrXY, qrXY))
    one_qr_canvas = one_qr_canvas.resize((int(qr_size_mm*required_resolution_px),
                                          int(qr_size_mm*required_resolution_px)))
    one_qr_canvas.save(form_full_path("TLTR" str(start_range n) ".pdf"), dpi=(required_resolution, required_resolution))


pil_paper_canvas = pil_paper_canvas.resize((int(paper_width_mm*required_resolution_px),
                                            int(paper_height_mm*required_resolution_px)))
# pil_paper_canvas.show()
pil_paper_canvas.save(form_full_path("TLTR_qr_A4.pdf"), dpi=(required_resolution, required_resolution))
  

Комментарии:

1. Был бы признателен за любой комментарий по этому поводу или направление поиска. Спасибо.

2. Для меня это похоже на сглаживание, присущее формату PDF, но я не эксперт в этом вопросе. en.wikipedia.org/wiki/Spatial_anti-aliasing

3. Спасибо за ваши комментарии @physicalattraction. Попытался изменить размер с фиксированного размера на масштаб / коэффициент, что не помогло. Тогда я понял, что PDF по своей сути сохраняется с разрешением 96 точек на дюйм, что и испортило мои отпечатки. Также попробую сглаживание.

4. Есть ли у ваших resize() команд возможность использовать выборку «БЛИЖАЙШЕГО СОСЕДА» вместо билинейной или бикубической?

5. @MarkSetchell Да, это (PIL) делает, в настоящее время использует BILINEAR. Для перевода qr-кода из двоичного в PIL я увеличиваю масштаб изображения, на более позднем этапе при сохранении я могу сохранить масштаб или уменьшить масштаб в зависимости от MM2PX_FACTOR . Я понял, что самая большая проблема связана с сохранением PDF, что значительно снижает разрешение (DPI) изображения с использованием PIL. Мне еще предстоит найти способ в PIL сохранить готовый к печати PDF-файл.

Ответ №1:

Я внес 3 изменения, чтобы исправить / обойти проблему:

  1. Вместо указания фиксированного числа для изменения размера переключился на масштаб (m * n).
  2. Используется lineType=cv2.LINE_AA для сглаживания, как предложено @physicalattraction

Это все еще нерешенная проблема, которая заключалась в том, что PIL сгенерировал PDF с разрешением 96 точек на дюйм, что не подходит для печати. Не удалось определить вариант использования готового к печати PDF (PDF / A или что-то в этих строках). Следовательно, переключился на генерацию PNG для генерации высококачественных qr-кодов.