Acceleration of the algorithm - scanning an image from a file

My code works here, but takes a couple of seconds longer, and it takes longer with large files, and I wanted to know if anyone could take a look at what I have and suggest some improvements that would help to do this faster.

Goal:

This is scanning a PDF file and searching for a bitmap image of a QR code, and it will return the code for it (decoding)

private void ScanQRPdf(string imagePath) { foreach (var item in Directory.GetFiles(imagePath)) { if (Path.GetExtension(item).ToLower() == ".png") { Bitmap b = new Bitmap(imagePath); try { QRCodeDecoder decoder = new QRCodeDecoder(); String decodedString = decoder.decode(new QRCodeBitmapImage(b)); rtbpdfData.Text += decodedString + "\n"; } catch (Exception ex) { } } } } static void AddQRTag(PdfSharp.Drawing.XGraphics gfx, int xPosition, int yPosition, string QRdata, string HRdata) { gfx.DrawRectangle(XBrushes.White, xPosition, yPosition, xPosition + 55, yPosition + 85); PdfSharp.Drawing.XImage xImage = PdfSharp.Drawing.XImage.FromGdiPlusImage(BuildQR(QRdata.ToUpper(), 3, QRCodeEncoder.ENCODE_MODE.ALPHA_NUMERIC, 2, QRCodeEncoder.ERROR_CORRECTION.M)); gfx.DrawImage(xImage, xPosition + 5, yPosition + 5, xImage.PixelWidth * .8, xImage.PixelWidth * .8); XFont font = new XFont("OCR B", 6); XTextFormatter tf = new XTextFormatter(gfx); tf.Alignment = XParagraphAlignment.Left; XRect layout = new XRect(xPosition + 5, yPosition + 55, 55, 30); tf.DrawString(HRdata.ToUpper(), font, XBrushes.Black, layout, XStringFormats.TopLeft); } 
+4
source share
4 answers

Based on your comments, if you need to process the upper left corner of the image, you can extract this part of the image using Bitmap.Clone .

In this case, I would reorganize your code like this:

 private void ScanQRPdf(string imagePath) { foreach (var decodedString in DecodeAllImagesInFolder(imagePath)) { rtbpdfData.Text += decodedString + "\n"; } } private static IEnumerable<string> DecodeAllImagesInFolder(string imagePath) { foreach (var item in Directory.GetFiles(imagePath, "*.png")) { using (Bitmap b = new Bitmap(imagePath)) { yield return DecodeTopLeftCorner(b); } } } private static string DecodeTopLeftCorner(Bitmap bitmap) { var rect = new Rectangle(0, 0, 100, 100); using (var topLeft = bitmap.Clone(rect, bitmap.PixelFormat)) { return new QRCodeDecoder().decode(new QRCodeBitmapImage(topLeft)); } } 
+2
source

The code that you went through is all right. The problem should be in the function QRCodeDecoder.decode. If you scan an image pixel by pixel using the Bitmap.GetPixel function, it will spend a lot of time. The best way would be to use unsafe code and convert the bitmap to BitmapData.

+3
source

A few things to try:

  • Filter files by extension as suggested by Carra
  • Declare and instantiate QRCodeDecoder only once
  • Add text using StringBuilder and assign it only once

It would be like this:

 private void ScanQRPdf(string imagePath) { var files = Directory.GetFiles ( path, "*.png", SearchOption.AllDirectories ); QRCodeDecoder decoder = new QRCodeDecoder(); StringBuilder sb = new StringBuilder(); foreach (var item in files) { Bitmap b = new Bitmap(imagePath); try { String decodedString = decoder.decode(new QRCodeBitmapImage(b)); sb.AppendLine(decodedString); } catch (Exception ex) { } } rtbpdfData.Text = sb.ToString(); } 

But I really don’t think this will solve your problem, that all minor improvements and your delay should be somewhere in the QRCodeDecoder and QRCodeBitmapImage , especially in the decode method, you should try to understand them better, and find out what it does internally. to improve the code.

+2
source

You can use GetFiles with type:

 string[ ] files = Directory.GetFiles ( path, "*.png", SearchOption.AllDirectories ); 
+1
source

All Articles