sungaila / PDFtoImage

A .NET library to render PDF files into images.
https://www.sungaila.de/PDFtoImage/
MIT License
144 stars 14 forks source link

Anti-Alias being applied causing distortion to barcodes #53

Closed markbeazley closed 6 months ago

markbeazley commented 6 months ago

Question

Not sure if its a problem with this library, or an issue with PDFium or I'm just not getting the right combination of parameters.

I'm trying to print shipment labels to a Zebra GK420d printer (203dpi), using PDFtoZPL and I've got it mostly working, however I noticed some issues with the 2D datamatrix barcode, where the elemets are rounded instead of square, I think I've found the culprit being the PDF to Image conversion, using this code

var pdfBytes = File.ReadAllBytes("example-label.pdf");

var images = PDFtoImage.Conversion.ToImages(pdfBytes, dpi:203, width:812, height:1218);

foreach (var image in images)
{
    var data = image.Encode(SKEncodedImageFormat.Png, 100);
    File.WriteAllBytes("label-test.png", data.Span.ToArray());
}

It seems anti-aliasing has been applied image Which is fine for the text elements of the label, but could result in issues reading the barcodes, especially after the image goes through the Image to ZPL conversion, although that might be tweak-able by adjusting the threshold value, but seems a bit to fragile to rely on. I thought it might be related to the scaling caused by the dpi, height and width settings, and removing those 3 from the above code seems to remove the anti-aliasing from the 2D datamatrix, but not the rest of the label, which is just plain confusing. image

Original PDF file, 300dpi formatted to print on 4inch * 6 inch labels

PNG file generated by above code label-test

PNG file generated by above code with dpi,width and height not set label-test-no-params

sungaila commented 6 months ago

Hi @markbeazley, the scaling is handled by PDFium. There are special flags for disabling anti-aliasing for text, images and paths that are not available in PDFtoImage/PDFtoZPL yet.

I'll test these flags and expose them as new optional parameters. I'll inform you as soon as there is something to test.

sungaila commented 6 months ago

So I've been digging into the render flags and noticed a bug that would explain your weird results: If both width and height are unset, the anti-aliasing on images is disabled (but not for text or paths).

This was not intended and I'm working on a fix right now.

sungaila commented 6 months ago

Hey @markbeazley, I'll introduce PDFtoImage.PdfAntiAliasing to control which parts should be anti-aliased. For compatibility reasons it defaults to PdfAntiAliasing.All.

You can test these new flags here (make sure to clear your browser cache): https://www.sungaila.de/PDFtoImage/

Here is how each flag affects your example PDF. Please note that your barcode is text using the IDAutomationC128XL font. So there is no way to turn off anti-aliasing for text and barcode individualy.

PDFtoImage.PdfAntiAliasing.Text

PDFtoImage.Conversion.ToImages(pdfBytes, width:812, height:1218, antiAliasing: PDFtoImage.PdfAntiAliasing.Text);

example-label_text

PDFtoImage.PdfAntiAliasing.Images

PDFtoImage.Conversion.ToImages(pdfBytes, width:812, height:1218, antiAliasing: PDFtoImage.PdfAntiAliasing.Images);

example-label_images

PDFtoImage.PdfAntiAliasing.Paths

PDFtoImage.Conversion.ToImages(pdfBytes, width:812, height:1218, antiAliasing: PDFtoImage.PdfAntiAliasing.Paths);

example-label_paths

markbeazley commented 6 months ago

Hi @sungaila that's brilliant thanks, updated to the new nuget packages and it works perfectly.