|
Thanks for the response. That was one of my thoughts too.
We need to keep the PDFs So, I'm concerned with the amount of processing time (Convert to image, process image, delete image) and or memory space (Convert all then delete after processing) available. We have thousands of documents and more coming in all the time.
If you find anything more on "doing it directly" let me know. I'm still looking. I think I've found an inexpensive off the shelf product that might do what I need (SimpleIndex), but, I still would like to know how to do it.
Thanks again.
|
|
|
|
|
I'm unlikely to find anything. I'm no longer working for a company that has anything to do with barcodes.
On that topic, If you decide to do this kind of work yourself, you should really use Berend's code and not mine. He made a lot of significant improvements on my code. His version is here
|
|
|
|
|
|
You'll have to extract the image stream objects from each page in the PDF.
Another way - use Ghostscript to convert the PDF to multiple JPGs and process those.
|
|
|
|
|
This barcode reader works for barcode 39 not for Barcode 39 Extension. I would like to know if there is any code available for reading barcode 39 extension.
|
|
|
|
|
As I made a lot of changes to qlipoth's code, I asked him if it would be OK if I published my version as a separate CodeProject article. He said yes, and you'll find it here:
Reading Barcodes from an Image - III[^]
Have fun with it
|
|
|
|
|
Hello,
Your code was just what I was looking for and it works great in the sense that even on a scan in fax quality it manages to find all Code39 barcodes. My problem was only: it finds a lot more than just the barcodes. Even if I use your relatively clean test image, the test app returns some false positives.
Preventing false positives
To be able to use your code to reliably recognize valid Code39 barcodes, I have added some code to filter for only barcodes starting and ending in "*" (I could not use the checksum solution of vbdotnetcoder2005, because our application needs to read barcodes without checksum).
Even after implementing the start/end character constraint, I still got some false positives with real-world data. Because of this, I have also put in some code for noise recognition. I noticed that in this part of the code noise was ignored:
somedata= parsePattern(new string(pattern));
dataString += somedata;
if (somedata == null)
{
index++;
... somedata == null means that the pattern was not recognized, but even if this happens several times in a row, the software would still consider the next valid Code39 bar as a part of the same barcode. In my version, if the index is incremented more than 10 times without finding a valid pattern, a pipe "|" is added to the dataString to indicate noise. With this, a further constraint could be added that a valid Code39 barcode should also not contain any noise. This removed all false positives in my test data, without reduction in recognition rate.
[update October 3, 2009] - optimized code for speed
When profiling the software, I found that it spent 80% of processing time in this single line of code:
bmp.RotateFlip(System.Drawing.RotateFlipType.Rotate90FlipNone); To get rid of that, I have rewritten the code to avoid bitmap rotation. The new version implements these optimizations:
1. The code now scans through the same image twice: first scanning top-to-bottom and then left-to-right with x and y coordinates swapped. This removes the need for 90 degrees rotation.
2. On each scan line, the pattern that is found is first parsed front-to-end, then the character array is reversed and the parsing is repeated with the mirrored pattern. This removes the need for 180 degrees rotation or page flip.
3. For black and white images, I followed a suggestion of Pandele Florin: instead of converting the image to 24bpp RGB, I leave the original image format in tact for B&W images. This saves a conversion inside LockBits, making it faster and reduces memory usage.
4. In the verticalHistogram function, use byte and short integer arrays instead of float. Integer arithmetic is slightly faster, and can be used because all pixel data are integer numbers.
In my previous test, the software needed about 7 seconds for 50 scans over a 300dpi A4 image. Improvements 1 and 2 reduce that to about 1 second. 3 reduces that to 0.6 second for a B&W image and 4 shaves off another 5% - 10% for both B&W and color images. The code is now over 10 times faster for B&W images!
[update October 4, 2009] - EAN and Code128 support
For barcode recognition in our Library Catalog software, my company needs EAN barcode support. I've added that, based on information from wikipedia. When testing this, I encountered a problem with narrow bar width calculation, that I also fixed in my latest code.
Since Code128 uses bar width measurements that are fairly similar to EAN, I could add that too. I used following resources for this part of the code: Code128 table, checksum calculation, barcode generator. The Code128 work is only briefly tested, I had only one real-world sample for this barcode type.
[update October 5, 2009] - EAN Supplemental Code support
Some products (mainly books and periodicals) have a 2-digit or 5-digit supplemental code next to the EAN code. I have added support for these codes, will be returned as a separate barcode starting with "S", followed by the detected digits.
The updated code can be downloaded here:
http://www.berend.com/download/BarCodeImaging2Source-20091005.zip
I have uploaded test scans for demonstrating EAN and Code128 barcode detection here:
http://www.berend.com/download/BarCodeImaging2-testscans.zip
modified on Monday, October 5, 2009 5:28 AM
|
|
|
|
|
Thank you!!!
|
|
|
|
|
I downloaded this project and copied the code into a Windows Mobile Project. The only things that wouldn't build were the flip and rotate parts, which I removed. But the app now produces run time errors.
|
|
|
|
|
The error is on this line:
BitmapData bmData = bmp.LockBits(new Rectangle(0, startheight, bmp.Width, endheight - startheight), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
Debug shows that the values of the items are (0, 0, 640, 48 - 0) and it says "Value does not fall within the expected range" (System.ArgumentException in System.Drawing.dll)
|
|
|
|
|
That is due to a "by design" difference in behavior of LockBits (read: Microsoft botched up the mobile implementation of LockBits and refuse to fix it). See this msdn forum thread:
Bitmap.LockBits Does Not Behave as Expected
To make it work in Windows Mobile, what you could do is to move the bmp.LockBits to VScanPageCode39 and lock the full image before calling ReadCode39 for each band. You would need new overloads for functions ReadCode39 and verticalHistogram that accept a BitmapData instead of Bitmap parameter.
P.S. It might amuse you to read what Steve Ballmer recently had to say about the Windows Mobile programming team: http://wmpoweruser.com/?p=8170
|
|
|
|
|
Hi friends I am trying to read values from barcode images can any help me how to achieve this one i am c#.net
|
|
|
|
|
Hello,
If I make a print screen from the image the example provides and paste it to Paint and then save it as a tiff image, for instance, I will still be able to read the barcode.
However, if I open Word and crete a barcode usinf a 30f9 font and than make a printscreen and paste it to Paint and, finally, save it to a tiff (or other image type) file, despite your program will find a barcode while performing a scan page, it get get the right data...
So, my question is, how are you generating the codebar images?
Is it necessary to include any sp+ecial character on the value of the codebar?
Thank you
|
|
|
|
|
To what i read in the sourcecode. The application only works for one ratio of the 3of9 barcode.
3of9 barcodes can have a barcoderatio. This is the ratio between the thinnest and the thickest barcode line.
So when you generate the barcode in word see if you can change the barcoderatio.
|
|
|
|
|
I had the same problem and looked into the cause. Please consider this enlargement from the leading edge of a barcode, that I generated using a Code39 TrueType font in MS Word. I used the MS Document Image Writer printer to create a tiff image directly from Word, then enlarged and measured it in Photoshop:
Click to view image in new window
The first dark bar encountered has a width of 4 pixels, being a "narrow" bar. The software assumes that the first bar encountered will always be a dark "narrow" bar and uses that to determine if other bars are "narrow" or "wide". A barcode is seen as a pattern of bars of alternating width in light and dark color.
Here is one example of the code that does that determination:
if ((i-nBarStart) > (nNarrowBarWidth))
{
As you can see, the comparison will go wrong because the "narrow" bars following the first one are not 4 pixels, but 5, 6 or even 7 pixels wide. All bars > 5 pixels will be regarded as "wide" bars by the software, and the barcode is thus not correctly recognized. Word consistently makes the white gaps wider than the black bars in a barcode font, hence the problem is so prominent when Word is used to create barcode bitmaps.
To solve the problem, I have applied a small change:
private const float WIDEFACTOR = 2.0f;
...
int nBarWidth = i - nBarStart;
if (nBarWidth > nNarrowBarWidth * WIDEFACTOR)
{
Now with this version of the code, a bar will not be considered to be "wide" unless it is at least twice as wide as the measured narrow bar width. In the example, only bars >= 9 pixels will be considered to be wide. With this change the barcode created by Word is correctly recognized. I have re-run the software against all my test images and I believe that the change does not negatively affect the detection rate.
|
|
|
|
|
Anyone care to give me some pointers on how to upgrade this project to read code 128 barcodes?
thanks in advance
|
|
|
|
|
First,Thanks for your code.
I have some question for you.
How to dectect a barcode if its image is too bad or it's a blur image?
How to indentify barcode region in a large image?
Rich + Handsome = Amorous
|
|
|
|
|
> How to dectect a barcode if its image is too bad or it's a blur image?
I don't think you can. Some image sharpening MIGHT help, but I don't know how to implement that. Blurred barcodes are like blurred pictures. If the information isn't there in the first place, nothing you can do will get it.
> How to indentify barcode region in a large image?
As said in postings earlier:
In my experience, most barcodes begin and end with *
However, I have also seen a model with a fixed number of characters, which is more difficult to parse out.
Also remember that there may be text on the same scan line as your barcode, so your result in the arraylist may be something like:
kjh4#u*SURPRISE*fvj
Still, it's pretty easy to parse out useful text from this.
The more scans you do, the more likely you are to pick up a barcode, but the longer it will take to scan.
|
|
|
|
|
I myseft use this code to recognize: Code 93, Code 128, EAN, UPC...
You know:
They're not belong to wide/narrow bar.
Most of these barcodes don't start with "*" character.
I have to archive accurate distance between bars. Maybe, that's why It's right in some cases.
Would you like to give me some comment?
Anyway, thanks for your reply.
|
|
|
|
|
I've had this code in production for quite sometime now, what I have noticed is that if you scan just the portion of the image that the barcode should be in it increases your chances of reading the barcode. I have noticed some other barcode commerical barcode reading libraries that have an algorithmn to find the "region" in to which the barcode is located. I'm not sure how one would go about coding this but it would defiantly increase the percentage of successful barcode reads.
|
|
|
|
|
Hi,
Do you have C# code for generating barcode based on the format that will read it by your program?
If you have any idea, please pass it on to me..
Thanks in advance.
Regards
M.Kumar
|
|
|
|
|
I don't. However, codeproject seems to. check out
http://www.codeproject.com/cs/media/GenCode128.asp
|
|
|
|
|
Hi Kumar
Do generate Bar code, At very first we need to add reference..."barcodelib"
And rest of the code goes like this (To generate and print)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.PointOfService;
using System.IO;
namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
pictureBox1.Image = null;
BarcodeLib.Barcode b = new BarcodeLib.Barcode(textBox1.Text);
b.EncodedType = BarcodeLib.TYPE.CODE39;
Image barcode = b.Encode();
pictureBox1.Image = barcode;
label1.Text = b.RawData;
barcode.Save("C:\\Barcode.jpg");
//System.Drawing.Imaging.EncoderParameters encodeParams= new System.Drawing.Imaging.EncoderParameters();
//encodeParams.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.ScanMethod, textBox1.Text);
//printDialog1.ShowDialog();
// printDialog1.PrinterSettings.PrinterName="HP LaserJet P2015 Series PCL 5e";
// printDialog1.AllowSomePages = true;
// System.Drawing.Printing.PrintDocument doctoPrint = new System.Drawing.Printing.PrintDocument();
//printDialog1.Document = doctoPrint;
//doctoPrint.Print();
}
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
System.Drawing.Font printFont = new System.Drawing.Font
("Arial", 35, System.Drawing.FontStyle.Regular);
// Draw the content.
e.Graphics.DrawString("Hi", printFont, System.Drawing.Brushes.Black, 10, 10);
}
}
}
If u have idea about how to interface digital camera to our windows application...plz revert back
Regards
Kiran
|
|
|
|
|
I justed wanted to let you know that I have successfully implemented this library and I have found that increasing the num of scans of the image greatly increases the success rate of finding a valid barcode. I also added a checksum function that makes certain that the code is valid.
Thanks,
Curtis
|
|
|
|
|
Could you post your improved source and demo here so everyone will benefit?
Thanks
We can't stop asking "WHY!!"
|
|
|
|
|