Pixelation of PIL generated image

Viewed 160

I am trying to generate PDF files from generated image. The generated PDF file has high level of pixelation on zooming in which is creating shadows during printing.

Image of zoomed in qrcode from PDF

Showing gray zone around qrcode modules and pixels (gray) which should be white otherwise. It does not matter if the desired_resolution matches or is lower than the resolution in which the original image was created.

enter image description here

What could be the issue and possible fixes?

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 Answers

I incorporated 3 changes to fix/workaround the issue:

  1. Instead of specifying fixed number for resizing, switched to scale (m*n).
  2. Used lineType=cv2.LINE_AA for anti-aliasing as suggested by @physicalattraction

That still one issue unresolved which was that PIL generated PDF @96dpi which is not good for printing. Was unable to figure the option to use Print-ready PDF (PDF/A or something on those lines). Hence switched to generating PNG to generate high-quality qrcodes.

Related