Code128 not reading properly

I have a document that was a word document, then we added the barcode using Aspose, opened in Word and saved it as a PDF then I have another program that grabs the pdf and gets the images from it then reads the barcodes.

On the provided document image it is getting the wrong value, and when I highlight the region I see why. It’s only reading part of the barcode.

Here is a chunk of sample code: (The orientation hints were not originally there but they also didn’t help)
MemoryStream msImage = new MemoryStream();
oPdfConverter.GetNextImage(msImage);
System.Drawing.Bitmap curPage = new System.Drawing.Bitmap(msImage);
oBarCodeReader = new BarCodeReader(curPage, BarCodeReadType.Code128);
oBarCodeReader.ImageBinarizationHints = Aspose.BarCodeRecognition.RecognitionHints.ImageBinarization.Grayscale;
oBarCodeReader.OrientationHints = RecognitionHints.Orientation.NoRotate | RecognitionHints.Orientation.Rotate180 | RecognitionHints.Orientation.Rotate270 | RecognitionHints.Orientation.Rotate90;

while (oBarCodeReader.Read())
{
string barcodeValue = oBarCodeReader.GetCodeText();

// initialize graphics object from the image
System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(curPage);
// draw the barcode edges
oBarCodeReader.GetRegion().DrawBarCodeEdges(g, new System.Drawing.Pen(System.Drawing.Color.Red, 1f));
curPage.Save(@“C:\temp\curPage.bmp”, System.Drawing.Imaging.ImageFormat.Bmp);

[more code to do work]

The DLL is the current version 5.5.0

The barcode value should start with the characters ‘TMG’ then 3 sets of numbers, 8 digits long each. Instead barcodeValue is ‘379427370101010867010110340101’ and (int)oBarCodeReader.GetCheckSum()[0] returns 2 (which I don’t even think is a valid character for Code128 checksum values).

Please take a look and let me know what you find.

Thank you,
-Doug

Forgot to mention the image created from the PDF (included in the attached zip), the barcode reads properly using an Android app on my phone.

Hi Doug,

Thanks for your inquiry. I tested your provided PDF sample against the latest build of Aspose.BarCode for .NET 5.5.0 and Aspose.Pdf for .NET 8.0.0. I can recognize the bar code image by using the following source code below:

var extractor = new PdfExtractor();

extractor.BindPdf(@"C:\temp\Direct Deposit Authorization.pdf");

extractor.ExtractImage();

// save images to stream in a loop

int count = 0;

while (extractor.HasNextImage())

{

count++;

// save to stream

MemoryStream stream = new MemoryStream();

string filePath = @"C:\temp\Output" + count + ".png";

extractor.GetNextImage(stream);

using (BarCodeReader reader = new BarCodeReader(stream, BarCodeReadType.Code128))

{

reader.OrientationHints = RecognitionHints.Orientation.Rotate90;

while (reader.Read())

{

Console.WriteLine(filePath + " -- Symbol:" + reader.GetReadType() + " Code :" + reader.GetCodeText());

}

}

}

Result:

C:\temp\Output1.png – Symbol:Code128 Code :TMG1000000000090000000800000001

Please let me know in case of further assistance or questions.

The difference between your code and mine is that your have Rotate90 and I need all possible rotations because the barcode can be printed in multiple locations. With my code it detects the barcode, but not a valid barcode. Finding a case in which a bug is not reproduced is not sufficient and is not a workaround, please file a bug report so that it can be fixed.

Ok, so I decide to try region scanning to workaround this bug which will allow me to use the rotate (kinda), I try using this page as a guide
(Read Barcode Properties|Documentation).


I am using an image created from the pdf converter which is
2550x3300, but I really just need to scan a 15% border around the edges
looking for a barcode that may have been placed on the page edge either
printed directly on the page or added later as a sticker. Since this is
potentially a human operation the sticker may be at either 90 or 270
degrees on the side borders or 0 and 180 degrees on the top or bottom.
The barcode I’m looking for will always be Code128 and I decide to read
in this order: LeftMargin, BottomMargin, RightMargin, TopMargin,
WholePage. I read until I find a barcode with specific information
(barcodes not matching a specific syntax are ignored and the read
continues).

So you set the region in the constructor, this seems quite
painful, but ok let’s do this:
oBarCodeReader =
new BarCodeReader(curPage, new System.Drawing.Rectangle(scanLeft,
scanTop, scanWidth, scanHeight), BarCodeReadType.Code128);

I run
my code and it decreases the performance by about 4 fold, strange, let’s
investigate. I assume the object doesn’t do any scan work until the
read method is
called, but the constructor is actually quite slow at about 550ms so I
wonder what else it could possibly be doing… so I switch back to the
constructor that doesn’t take a region rectangle which takes about
100ms. This still seems slow to me but 400ms just to slice an image
up?? So I do it myself:

System.Drawing.Bitmap newCurPage = new System.Drawing.Bitmap(scanWidth, scanHeight);
newCurPage.SetResolution(curPage.HorizontalResolution, curPage.VerticalResolution);
System.Drawing.Graphics newGraphic = System.Drawing.Graphics.FromImage(newCurPage);

newGraphic.DrawImage(curPage, 0, 0, new
System.Drawing.Rectangle(scanLeft, scanTop, scanWidth, scanHeight),
System.Drawing.GraphicsUnit.Pixel);
newGraphic.Dispose();
oBarCodeReader = new BarCodeReader(newCurPage, BarCodeReadType.Code128);

Oh
wow, now we’re looking at about 100ms for the constructor the first time, then only 25ms for each time after that. Tthese times include my code to splice the image since that is the equivalent part of the work I would assume that constructor overload would do. I suppose I
can work with that constructor time so we’ll move on.

While scanning the left border I
need to scan 90 and 180 degrees, which means I have to do two scans per
margin side, then I still have the time of the full page scan if I haven’t found a barcode by that time yet. Unfortunately due to the slow pdf-> image → scan performance I’ve gone from about 9 seconds a page (which is already a long time) to almost 15 seconds a page (and even longer if I have more pages w/o barcodes than with). It’s about 2 seconds per region plus 4-5 seconds for a full page scan so if there are no barcodes on the page it could take as long as 20 seconds just to try to scan it. All this because the WholePage scan doesn’t return the correct results.

Worth noting, it does not scan the proper value at Rotate90 for me, but it does at Rotate270. In any case, it’s still a bug that it returns an invalid barcode when doing a full page scan w/ no rotational hint… but due to the poor performance of the barcode recognition I still do not see a feasible workaround and would like to hear your suggestions.

Hi Doug,


Thanks for the information. I would like to update you that you are using a PdfConverter class. It converts a PDF file pages to images. Whereas I’m using a PdfExtractor class. It extracts images and text from PDF document. In my source code, you can recognize the bar code image without setting orientation of 90 degrees or even you can set all possible rotations as I can see in your source code. Could you please share version details about the Aspose components? Because I suspect you are using some old versions.

Second, when I tried to use the PdfConverter class. I’m unable to recognize the bar code image. I have logged this problem under ticket id BARCODENET-33569 in our issue tracking system. Your request has also been linked to this issue and you will be notified as soon as it is resolved and available for the public use. We’re sorry for the inconvenience.

Please let me know in case of further assistance and comments.

I am using an older Aspose.PDF component and we do plan on updating the Aspose.PDF component to the latest sometime
in the next week, but we have a lot more code using that and it is quite
out of date which means we will need to re-code some components and do a lot of testing. Since you were able to duplicate the problem with the latest PDFConverted, that doesn’t seem to be the problem (Aspose.Barcode and Aspose.BarcodeRecognition are the latest).

Unfortunately I’m not sure that I can use the extractor piece for a couple of reasons:
1. If I have a PDF that was scanned in from a copier then it’s all just one image and will basically result in the same image as the PDF Converter, correct? This is most often going to be our scenario.
2. If I have a PDF with lots of images, I have to process each one individually which… based on the speed of the barcode recognizer could mean a single page of a document could take significantly longer, correct?

Please let me know if my assumptions are correct or not, and if you have any other suggestions for a work around.

Also, can you shed some light on the constructor issue with the image rectangle and why it seems to be such a drastic performance hit when compared to slicing the image myself? Is there other work being done that doesn’t happen in my work around or is there a bug causing performance issues with that specific overload?

Hi Doug,

Thanks for your inquiry. First off, please note that each new release contains many improvements, bug fixes and new features. So, we always suggest our customers to use the latest version of Aspose components. Second, the PdfConverter by default produces the image with less quality than PdfExtractor. The PdfExtractor provides the ideal black white sequence. So I’ll not agree with your first point. It is true that you will have to process each one bar code image individually but it does not mean it will take significantly longer because performance depend on file complexity, the size of the image file and RAM. But any ways please note that you can significantly speed up the processing by reading bar code from a specific region of the image as you will have to process only a small portion of the image. I’m able to recognize the bar code image using following source code below but the code text is incorrect.

Document pdfDocument = new Document(@“C:\temp\Direct Deposit Authorization.pdf”);

for (int i = 1; i <= pdfDocument.Pages.Count; i++)

{

PdfConverter converter = new PdfConverter();

converter.BindPdf(@"C:\temp\Direct Deposit Authorization.pdf");

converter.StartPage = i;

converter.EndPage = i;

converter.RenderingOptions.BarcodeOptimization = true;

converter.Resolution = new Aspose.Pdf.Devices.Resolution(300);

converter.DoConvert();

MemoryStream stream = new MemoryStream();

converter.GetNextImage(stream, ImageFormat.Png);

Bitmap bm = new Bitmap(stream);

using (BarCodeReader reader = new BarCodeReader(new Bitmap(stream), new System.Drawing.Rectangle(40, 1800, 500, 1400), BarCodeReadType.Code128))

{

Stopwatch stopWatch = new Stopwatch();

stopWatch.Start();

while (reader.Read())

{

Console.WriteLine(filePath + " -- Symbol:" + reader.GetReadType() + " Code :" + reader.GetCodeText() + " Time:" + stopWatch.Elapsed.Seconds);

}

}

}

Constructor without Rectangle is taking 20 seconds to recognize the bar code image:
BarCodeReader r = new BarCodeReader(stream, BarCodeReadType.Code128);

Constructor with Rectangle is taking 6 seconds to recognize the bar code image:

BarCodeReader reader = new BarCodeReader(new Bitmap(stream), new System.Drawing.Rectangle(40, 1800, 500, 1400), BarCodeReadType.Code128);

So I believe its performance is much better than the constructor without Rectangle. I have attached the sample bar code image for your reference. Please let me know in case of further assistance or question.

By default it may create less quality, but I am not using the default settings, which is why curPage.bmp is so large… here is my setup:
PdfConverter oPdfConverter = new PdfConverter();
oPdfConverter.BindPdf(msInPdfDoc);
oPdfConverter.StartPage = startPage;
oPdfConverter.EndPage = endPage;
oPdfConverter.Resolution = 300;
oPdfConverter.DoConvert();
while (oPdfConverter.HasNextImage())
{
MemoryStream msImage = new MemoryStream();
oPdfConverter.GetNextImage(msImage);
System.Drawing.Bitmap curPage = new System.Drawing.Bitmap(msImage);
[…]

I understand that there are important updates to using the newest tools, however since the problem is reproducible by you with the current version and a bug report has already been opened for that I don’t think we need to spend any more energy debating that it won’t solve my problem and therefore is not a valid workaround solution.

When I ask about the performance I am simply asking about the constructor performance. Try it with the image I uploaded. Read the image into a Bitmap object, get the current DateTime.Now value, then call the constructor without the rectangle overload get the time difference, get the current DateTime.Now and call the constructor with it and get the time difference. Do it a second time in the same program to remove any overhead related to loading references and on the second load I would expect you to see the same results I am seeing, massive performance hits on using that overload. Yes it’s faster to scan the smaller image that the whole page but I can’t believe I’m giving up almost 400ms just for your overload to slice the image for me when the quick code block I provided does that work plus the constructor that doesn’t do the slice in about 25ms. That’s why I’m wondering if it is doing more than just slicing the image when I use the constructor with the rectangle overload.

Also, as mentioned before I don’t know exactly where the barcode is going to be, I only know that it can be anywhere in the page margin. This means I have to slice each margin, that’s 4 scans. Let’s say that takes 6 seconds each, at 4 scans without any other overhead that’s 24 seconds vs the 20 to scan the whole page. Then just to be confident if I don’t find one in any of the 4 margins I still have to do a page scan so now were at 44 seconds if the page doesn’t have a barcode (which is also valid, not all pages for my requirements need to have a barcode). So at this point, we’re still not at a good workaround solution unfortunately. I understand if you don’t have one that meets my requirements, as bug fixes take work, but if that is the case then I would like to know for sure… otherwise with the requirements in mind I am still hoping that you have a workaround suggestion.

Hi Doug,

Thanks for the information. I managed to replicate the performance issue. It has been logged under ticket id BARCODENET-33572 in our issue tracking system. Your request has also been linked to this issue and you will be notified as soon as it is resolved and available for the public use. We’re sorry for the inconvenience.

Bitmap myBmp = (Bitmap)Bitmap.FromFile(@“C:\AB\test100\curPage.bmp”);

Stopwatch stopwatch = new Stopwatch();

stopwatch.Start();

BarCodeReader read = new BarCodeReader(myBmp, BarCodeReadType.Code128);

stopwatch.Stop();

Console.WriteLine("Milliseconds:" + stopwatch.ElapsedMilliseconds);

stopwatch.Start();

BarCodeReader read2 = new BarCodeReader(myBmp, new System.Drawing.Rectangle(49, 1129, 11, 460), BarCodeReadType.Code128);

stopwatch.Stop();

Console.WriteLine("Milliseconds:" + stopwatch.ElapsedMilliseconds);

Results:


Debug mode:

Milliseconds:305

Milliseconds:1232

Exe mode:

Milliseconds:172

Milliseconds:715

Please let me know in case of further assistance or questions.

PS: Please note that there is no guarantee that there is such a work around at the moment, you may need to wait for the original fix.

Hi Doug,

Thanks for your patience. Good news for you is BARCODENET-33572 has now been resolved and its fix will be included in the next version of Aspose.BarCode for .NET (5.6.0). Which is expected after one or two weeks. We will inform you via this forum thread as soon as the new release is published.

Hi Doug,

Thanks for your patience. Good news for you is BARCODENET-33569 has now been resolved and its fix will be included in the next version of Aspose.BarCode for .NET (5.6.0). Which is expected in the current or next week. We will inform you via this forum thread as soon as the new release is published.


The issues you have found earlier (filed as BARCODENET-33572) have been fixed in this update.


This message was posted using Notification2Forum from Downloads module by Aspose Notifier.

The issues you have found earlier (filed as BARCODENET-33569) have been fixed in this update.


This message was posted using Notification2Forum from Downloads module by Aspose Notifier.

While the new dll does seem to better recognize an image on a full page now, for some reason it doesn’t read when I slice the page to the border I expect to see a barcode on.

Please attempt to scan the attached file, with orientation hint of Rotate90 and ImageBinarizationHint of Grayscale using Aspose Barcode Recognition 5.6.2.0.

oBarCodeReader = new Aspose.BarCodeRecognition.BarCodeReader(newCurPage, Aspose.BarCodeRecognition.BarCodeReadType.Code128);
oBarCodeReader.ImageBinarizationHints = Aspose.BarCodeRecognition.RecognitionHints.ImageBinarization.Grayscale;
oBarCodeReader.OrientationHints = Aspose.BarCodeRecognition.RecognitionHints.Orientation.Rotate90;
while (oBarCodeReader.Read())
{
//Never hit
}

Hi Doug,


Thanks for your inquiry. I would like to update you that you can recognize this bar code image without applying orientation hint. It is because the read method also auto detects the orientation of the bar code so far it’s quite possible to recognize a bar code having 90 degrees without setting orientation hint.

Second, I have logged an investigation to check further into the matter. This task has been logged under ticket id BARCODENET-33634 in our issue tracking system. Your request has also been linked to this issue and as soon as we have made some significant progress, we would be more than happy to update you as well. We’re sorry for your inconvenience.

Hi Doug,

We have a good news for you is BARCODENET-33634 has now been resolved and its fix will be included in the next version of Aspose.BarCode for .NET (5.7.0). Which is expected after 3 or 4 weeks. We will inform you via this forum thread as soon as the new release is published.


The issues you have found earlier (filed as BARCODENET-33634) have been fixed in this update.


This message was posted using Notification2Forum from Downloads module by Aspose Notifier.