Jonasfj.dk/Blog
A blog by Jonas Finnemann Jensen


December 30, 2009
ZBar bindings for C#
Filed under: Computer,English,zbar-sharp by jonasfj at 6:58 am

gtkzbar-sharp-exampleAs part of the food management system my group made this semester, we wrote bindings for ZBar and based on those a bar scanning widget for Gtk#. Anyway, I figured it might be useful somebody else, so I’ve been using a few days cleaning up the ZBar bindings, extracting the Gtk# widget from our UI-mess and writing a simple example of how to use it.

The result is bindings for a subset of ZBar and a Gtk# bar scanning widget. I don’t intend to maintain the source, but if you find any bugs etc. or wish to start a project for the bindings, please leave a comment…

The example application using the bar code scanning widget can be seen on to right. Note: this was a really lousy webcam :). The check-mark appears when a bar code have been recognized and then fades away.

In Foodolini we used HAL to detect webcams as they were plugged, however, having heard that Ubuntu will be deprecating HAL, I didn’t care to clean up the source for this feature. If you interested it can be found in the source for Foodolini. And if anybody should happen to know how to detect webcams, distro independently, without HAL, please leave a comment…

51 Comments »

  1. […] the time or the reason… Anyway, as I discovered a minor bug in the zbar-sharp bindings I recently released… I figured this might just be the kind of project I could push to github, and either forget […]

    Pingback by Jopsen.dk/blog — January 31, 2010 @ 8:02 am

  2. zbar no… but just use the binaries the project ship… Or ask them…

    zbar-sharp can probably be opened directly in VS… Haven’t tried though…
    You can download the source from: http://github.com/jonasfj/zbar-sharp

    Comment by Jonas Finnemann Jensen — May 11, 2010 @ 5:32 am

  3. Hi Jopsen,
    This is very useful. Do you know how to build ZBar in Visual Studio? I could not find any information. The main reason that I am asking is that I want to make a Pocket PC program.

    Best regards,
    Alper

    Comment by Alper Yaman — May 11, 2010 @ 5:17 am

  4. The example given should work with VS, but requires gtk-sharp, if you don’t want to play install that I’ve pushed a new example (bmp-scanner) to github.com/jonasfj/zbar-sharp.

    The bmp-scanner example is hard coded to the image it distributed with… But it works and shows how zbar-sharp can also be used.

    Remember to link against zbar-sharp in your project file, and put libzbar-sharp.dll and libzbar.dll next to the binary when running it.

    Note the binary libzbar.dll (the one from zbar.sf.net) may be named zbar.dll or libzbar-1.dll or something, but it needs to be renamed to libzbar.dll

    Let me know if have any problems building it… I don’t have time to test it on a Windows VM right now…

    Comment by Jonas Finnemann Jensen — July 9, 2010 @ 11:01 am

  5. Hey

    I’ve just spend 30mins or so trying to use your bindings in windows / visual studio but am yet to be successful.

    Any help you can give? example C# windows code perhaps?

    Thanks
    NB: Im trying to use your bindings to enable me to run ZBAR with C#, and to make an app to achieve something similar to that of yours above, ie shows web cam picture, detects barcode and then use that in the app. (bascially make the output of ZBAR usable in a c# proggy)

    Comment by birdi3 — July 9, 2010 @ 7:09 am

  6. Thanks for your reply!

    I had a play further yesterday (before reading your comment) and only got as far as hitting an error such as ‘Unable to load DLL libzbar”, despite having it renamed and in line with the binary, (ie in the debug folder, as well as in other locations as I tried to test it), but then managed to get this working by moving in the other dll’s from ZBAR (..really should have done that first time round)

    With this in mind and your help above, I have since been able to get your example working! Huge thanks for the swift reply and good example, hopefully it will be very useful for others! Next challenge is to get it reading directly from the cam in Windows. Wish me luck and I hopefully wont be back too soon! πŸ˜›

    Thanks Again

    Comment by birdi3 — July 10, 2010 @ 7:43 am

  7. If you’re on Windows:
    The video capture in zbar on Windows uses Video For Windows. A very old legacy API, you may wish to write your own capturing code that uses whatever is hot in Windows, probably DirectShow. And give the captured images to zbar…
    I have an example where I read a barcode in a BMP:
    http://github.com/jonasfj/zbar-sharp/tree/master/example/bmp-scanner/

    If you write such code please share…

    If you’re on Linux, you can get the video device string from HAL. I did this using dbus, the code is available at http://jopsen.dk/blog/2009/12/foodolini-a-food-management-system/
    However, HAL is being deprecated… So it’s probably better to get it elsewhere. If you find out how, let me know…

    I don’t know how to discover the PixelFormat, if you’re talking about bmp from files, I suggest you find a bmp reader/parser or read the specification…

    – Best of luck…

    Comment by Jonas Finnemann Jensen — July 28, 2010 @ 2:50 pm

  8. Any advice how to discover the PixelFormat of a bmp image and how to discover the video device string?

    Comment by Varro — July 28, 2010 @ 7:58 am

  9. Thank you for the fast reply.
    Currently i’m working on windows system, trying to create a piece of code which makes the bmp and jpeg scanning (like bmp-scanner you made).
    Thank you for the advice and thank you for your library.
    Regards.

    Comment by Varro — August 1, 2010 @ 3:09 am

  10. @Lars:
    zbar-sharp is not a C# version/clone of zbar, it’s just C# bindings for zbar.

    Regarding your issues you should make clone of:
    http://github.com/jonasfj/zbar-sharp
    E.g. make sure you’re using the latest development version, not that there’s a lof of active development… But it might have some fixes…

    Second, you must have the libzbar.dll placed next to your .exe file along with the zbar-sharp.dll. During this you’ll notice that they binary zbar dll distributed for windows is called libzbar0.dll or something, if so you MUST rename it to libzbar.dll
    Also remember to copy the other .dlls that is distributed with libzbar.dll next to your .exe file…

    Are you having any problems building zbar-sharp.dll ? In visual studio ?
    And if not have you tried to make a VS.Net project for the bmp-scanner example ? Can you build it ? Can you run it ? At what point does it fail…

    By the way, if you think this turns into a longer discussion you should consider opening an issue at: http://github.com/jonasfj/zbar-sharp/issues

    Regards Jonas Finnemann Jensen.

    Comment by Jonas Finnemann Jensen — September 17, 2010 @ 11:43 am

  11. Hello,
    thanks a lot for programming a c# version of zbar.
    I hope i can use ist in a Visual Studio c# Program.
    But In any way i try to run it, I fail.

    Now I tried MonoDevelop to Build a runnable Version.
    I failed too and I don’t understand the error. Its something
    about the Form Builder or probably somthing about me…

    Actually I Have a running Application which use Zbar in a very bad way.
    The zbar download for Windows includes a zbarimg.exe to scan images for
    Barcodes. Now my Program takes an image out of an Webcam Video Stream and
    Saves it on harddrive. Then I scan it with zbarimg.exe and read back the
    console output. Its very slow. Now I hope i can use zbar-sharp.

    Iam sitting here a whole day and it doesnt run yet…

    MFG.: Lars

    Comment by Lars — September 17, 2010 @ 5:56 am

  12. Hello again,
    now I can build the projects with VS.net
    And Iam able to run the bmp-scanner, too.
    I dont know what I had done the first Time but now it works.
    Iam very glad
    Now I wonna ask you for a tip:
    I need a Zbar.Image (binary) I have a System.Drawing.Bitmap
    How can I become my bitmap in the Zbar.Image?
    I testet:
    System.IO.MemoryStream MS = new System.IO.MemoryStream();
    Bitmap.Save(MS, Bildformat);
    MS.Seek(54, SeekOrigin.Begin);
    byte[] data = new byte[Bild.Width * Bild.Height * 3];
    MS.Read(data, 0, data.Length);
    Zbarimage.Data = data;

    When I run it, zbar doesnt find any Barcodes
    MFG.: Lars

    Comment by Lars — September 24, 2010 @ 4:07 am

  13. Hi Lars,

    I think the Bitmap needs to be in the right format (RGB3), afaik System.Drawing.Bitmap can have different underlying representations… And then you need to run ZBar.Image.Convert(0x30303859) after copying the data to ZBar.Image…

    Also note that some a BMP is header file… The conversation I did in BMPScanner is hardcoded and won’t work in general cases… So you probably need to read something about Bitmap and GREY/Y800 format.

    I think it’s fairly simple, but I don’t have time to hack it these days…
    But please do send me an example if you come up with something better, so that others may also benefit from it…

    Comment by Jonas Finnemann Jensen — September 24, 2010 @ 4:23 am

  14. Hi,

    Here is my code:
    I chnaged my Original-Code a little. I hope there arent too many mistakes…

    Public Function ScanBitmap(ByVal Image As System.Drawing.Bitmap, ByRef Seriennummer As String, ByRef typ As String, ByRef qual As Integer)
    Dim NewBitmap As New Bitmap(Image.Width, Image.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb)
    Dim NewGraphics As Graphics = Graphics.FromImage(NewBitmap)
    NewGraphics.DrawImage(Image, New System.Drawing.Rectangle(0, 0, Image.Width, Image.Height), 0, 0, Image.Width, Image.Height, GraphicsUnit.Pixel)

    Dim width As UInteger = Image.Width
    Dim height As UInteger = Image.Height
    Dim data As Byte() = New Byte(width * height * 3 – 1) {}

    Using fs As New IO.MemoryStream
    NewBitmap.Save(fs, System.Drawing.Imaging.ImageFormat.Bmp)
    ‘Skip the header
    fs.Seek(54, SeekOrigin.Begin)
    fs.Read(data, 0, data.Length)
    End Using

    ‘Create an empty image instance
    Dim img As New ZBar.Image()
    img.Data = data
    ‘Set the data property
    img.Width = width
    ‘Set width and height
    img.Height = height
    img.Format = &H33424752
    ‘Trying with RGB3, as I know it’s 24bit BMP
    Dim grey As ZBar.Image = img.Convert(&H30303859)
    ‘Convert to GREY/Y800
    ‘Create a scanner
    Using scanner As New ImageScanner()
    scanner.Cache = False
    ‘Scan the image
    scanner.Scan(grey)
    End Using

    ScanBitmap = False
    qual = 0
    typ = “”
    Seriennummer = “”
    For Each sym As Symbol In grey.Symbols
    qual = sym.Quality
    typ = sym.Type
    Seriennummer = sym.Data.ToString
    ScanBitmap = True
    Next
    grey.Dispose()
    NewBitmap.Dispose()
    img.Dispose()

    End Function

    Comment by Lars — October 14, 2010 @ 12:27 am

  15. @Lars,
    It looks good to me… I’ll consider using the Bitmap class for scanning in my example code.
    When I get around to updating it someday…
    – Thanks for figuring it out πŸ™‚

    Comment by Jonas Finnemann Jensen — October 14, 2010 @ 2:05 am

  16. I have a problem when I have to destroy the image.
    in C#
    zbar_image_destroy(this.handle);
    ERROR –>Invalid access to memory location. (Exception from HRESULT: 0x800703E6)
    in VB
    zbar_image_destroy(this.handle);
    ERROR –>A callback was made on a garbage collected delegate of type ‘BCReader!BCReader.ZBar.Image+zbar_image_cleanup_handler::Invoke’. This may cause application crashes, corruption and data loss. When passing delegates to unmanaged code, they must be kept alive by the managed application until it is guaranteed that they will never be called.
    pls help

    Comment by thedarkking — November 22, 2010 @ 11:59 pm

  17. @thedarkking,
    I knew this bug would come back and haunt me… But I haven’t been able to reproduce it reliably, and I never suspected that it was the delegate that was the issue.

    Anyway, having looked at [1], I’m starting to think it was the delegate, I’ve tried to make a fix, and pushed it to github you can find it here:
    https://github.com/jonasfj/zbar-sharp/tree/delegate-fix

    Please do confirm if this fix works, so I can merge it into master branch, and next release…

    [1] http://www.mono-project.com/Interop_with_Native_Libraries#Memory_Boundaries

    Comment by Jonas Finnemann Jensen — November 23, 2010 @ 10:55 am

  18. Hey

    I was wondering if you could help clear up some confusing im having using your project!

    Image img = new Image();
    img.Data = data; //Set the data property
    img.Width = width; //Set width and height
    img.Height = height;
    // Fine up to here…

    img.Format = 0x33524742; // Whats this? As far as I can work out its the “format” of the file, and can be obtained from the headers…?
    // can you advise on how to obtain it from the header? and what it actually does? or where there is a list of sensible things->hex? is that just for rgb3 24bit?
    // i found what I thought was a list and tried the hex value that matched up to a 32bit rbg3 and it threw an error…

    Image grey = img.Convert(0x30303859); //Convert to GREY/Y800

    Thanks πŸ™‚
    PS: im a big fan of the work you did with zbar

    Comment by bob — November 23, 2010 @ 12:58 pm

  19. @bob,
    The format is a FOURCC code, I think, take a look at: http://fourcc.org
    Ideally, we should probably have some enum with these codes in… But I never really cared to figure out how they worked… πŸ™‚

    zbar can only read images of format GREY/Y800 (fourcc code: 0x30303859).
    But zbar can convert from RGB3 (0x33524742) to GREY/Y800. It can also do other conversations, but I haven’t tried any of that.

    What I mean by “obtained from header” is that in the header of the BMP file it should say what format it’s in… But how to read that I don’t know or care…

    I recommend using System.Drawing.Bitmap to load custom images, and then convert to RGB3 using that, before creating an instance of ZBar.Image (see Lars’ code above)
    But I’m sure it can be done more efficiently…

    Comment by Jonas Finnemann Jensen — November 23, 2010 @ 1:45 pm

  20. Thanks @bob,
    This bug is fixed.
    Now works very well.
    I use it to read barcodes from images that are in the database, for this I needed to free memory.

    Comment by thedarkking — November 24, 2010 @ 4:38 am

  21. Thanks for the confirmation…
    I’ll merge the patch into master… It’s really great to fix this one bug that’s been hiding for so long… πŸ™‚

    Comment by Jonas Finnemann Jensen — November 24, 2010 @ 8:24 am

  22. Nice… I recently pushed a new method that lets you create an image from an instance of System.Drawing.Image, but it uses some drawing stuff and is rather expensive…
    The UnlockBits thing look really neat… I’ll try that and add a specific overload for System.Drawing.Bitmap

    In case anybody wonders the source is maintained here:
    http://github.com/jonasfj/zbar-sharp

    Comment by Jonas Finnemann Jensen — January 13, 2011 @ 2:22 pm

  23. Here is how to convert a tiff

    private byte[] ConvertBitmap(Bitmap bitmap)
    {
    //Code excerpted from Microsoft Robotics Studio v1.5
    BitmapData raw = null; //used to get attributes of the image
    byte[] rawImage = null; //the image as a byte[]

    try
    {
    //Freeze the image in memory
    raw = bitmap.LockBits(
    new Rectangle(0, 0, (int)bitmap.Width, (int)bitmap.Height),
    ImageLockMode.ReadOnly,
    PixelFormat.Format24bppRgb
    );

    int size = raw.Height * raw.Stride;
    rawImage = new byte[size];

    //Copy the image into the byte[]
    System.Runtime.InteropServices.Marshal.Copy(raw.Scan0, rawImage, 0, size);
    }
    finally
    {
    if (raw != null)
    {
    //Unfreeze the memory for the image
    bitmap.UnlockBits(raw);
    }
    }
    return rawImage;
    }

    private void button2_Click(object sender, EventArgs e)
    {
    System.Drawing.Image image = System.Drawing.Image.FromFile(“test.tif”);
    Byte[] data = ConvertBitmap((Bitmap)image);
    ZBar.Image zimage = new ZBar.Image();
    zimage.Data = data;
    zimage.Width = (uint)image.Width;
    zimage.Height = (uint)image.Height;
    zimage.Format = ZBar.Image.FourCC(‘R’, ‘G’, ‘B’, ‘3’);
    using (ZBar.ImageScanner scanner = new ImageScanner())
    {
    using (ZBar.Image grey = zimage.Convert(ZBar.Image.FourCC(‘Y’, ‘8’, ‘0’, ‘0’)))
    {
    scanner.Scan(grey);
    List symbols = new List(grey.Symbols);
    }
    }

    }

    Hope this helps πŸ™‚

    Comment by Justin — January 13, 2011 @ 12:21 pm

  24. Hi,

    i like this approach a lot and would also like to use it. I am facing some problems. I am using the bitmap scanner and was expecting similar results to what zbarimg is producing. But the result i am getting are rather frustrating. I use another component to capture a video stream and take an image and scan it afterwards. Uploaded an image which is working fine in a zbarimg and does not have a result with the bitmap scanner http://dl.dropbox.com/u/17637020/test.bmp.

    am i missing something here?

    Comment by Daniel — January 19, 2011 @ 9:18 am

  25. @Daniel,
    I assume you’re using latest version of zbar (0.10), right? and zbar-sharp master from github (not the one available for download as tarball).
    Support for QR codes is very new, I haven’t tested it, and it’s only recently made it to master branch at github.com/jonasfj/zbar-sharp

    When, you say the bitmap scanner, is that the one in example/bmp-scanner ?
    And what is the result? Does find anything, or what? bmp-scanner, doesn’t really print anything useful, it’s just an example…

    Comment by Jonas Finnemann Jensen — January 20, 2011 @ 3:47 am

  26. Hi thank you for your reply,

    i took the latest master version from github from the link you have posted (13. January). in combination with the latest zbar (0.10).

    The Bitmap scanner is the example you published at github as well. The core code is this:

    System.Drawing.Image img = System.Drawing.Image.FromFile(file);

    List symbols = scanner.Scan(img);
    foreach (Symbol symbol in symbols)
    Console.WriteLine(“t” + symbol.ToString());

    the file is the bitmap i send. The output is empty, so no symbols where found. The zbarimg.exe detects it and i also looked into that code (zbarimg.exe) and did not see any fancy stuff like configuration settings or similar things. so i assume the only different thing is the way how the image is converted. i was also not able to scan the following image too (an example image from zbar which also works with zbarimg which is an normal bar code): http://dl.dropbox.com/u/17637020/Just_right.png

    besides the image conversion i do not see where the problem might be.

    Comment by Daniel — January 20, 2011 @ 9:18 am

  27. @Daniel,
    Sorry, for the reply time…

    I’m thinking that maybe zbar can consume color images… Maybe even RGB3 (24bit BMP), see:
    http://sourceforge.net/apps/mediawiki/zbar/index.php?title=Supported_image_formats

    Update: I had a look at the code and zbarimg uses ImageMagick for conversation to greyscale… Which is better than the greyscale conversation in zbar…

    Comment by Jonas Finnemann Jensen — January 29, 2011 @ 5:59 am

  28. I just finished a project for work that batch scans 3 of 9 barcodes from jpg files.

    1. try to read zbar installdir key from the regestry
    2. if i can read it, show message that zbar isnt installed and launch zbar installer.
    3. use that information to make a path from zbarimg.exe
    4. have a way to select a folder on the UI.
    5. for each file in the selected folder.
    6. if its a jpg
    7. make a new process
    8. set the path to zbar that we worked out from the regestry
    9. create the command line arguments including filename of the current file (including –raw command)
    10. redirect both standard output and error output to textboxes on the form.

    I guess i could have just used this…. oh well, i might rewrite it tomorrow at work to see if there is any speed increase.

    Comment by steveo — February 16, 2011 @ 4:15 am

  29. @steveo
    zbar is LGPL, I don’t see why you don’t just distribute it with your application. LGPL is easy to comply with (zbar-sharp is also LGPL).

    Also, if you performance in an issue why don’t you do it in C? Or at least the core functionality… Using ImageMagick for gray conversation might also yield better results.

    But you’ll probably also experience a small performance improvement from using zbar-sharp… Because, unlike Linux, launching process on Windows is inherently slow.
    (Do consider using latest sources from the master branch at github, they have fewer bugs).

    Comment by Jonas Finnemann Jensen — February 16, 2011 @ 12:55 pm

  30. @Jonas
    I did manage to we write my program.

    Using the same 5 600dpi jpg images.

    1. My program using command line zbar = 20 seconds.
    2. My program using your library = 27 seconds.
    3. My program using your library with cropping = 10 seconds.

    Because we are feeding the documents through a document feeder the barcode is always aprox in the same spot in the images.

    so 10 hours of processing will now be 5 hours hopefully πŸ˜€

    Comment by steveo — February 16, 2011 @ 8:58 pm

  31. @steveo

    Okay, if you’re running that high resolution I see that performance might be an issue…
    But there’s a lot of memory copying in zbar-sharp, so you might want to do the croping in zbar-img.exe, and then maybe extend the program to loop through all files in the folder (to avoid spawning new processes).

    Comment by Jonas Finnemann Jensen — February 17, 2011 @ 3:22 am

  32. […] previously caused applications to crash at random. A thanks to the nameless commentor by the name thedarkking, who’s comment finally gave me a clue as to where the bug […]

    Pingback by Jopsen.dk/blog — March 19, 2011 @ 9:51 am

  33. @Daniel, @Jonas

    I believe figured out the reason for the difference between the c# wrapper result and zbarimg.exe

    The issue is that windows bitmaps are stored upside-down in memory, so your conversion to ZBar.Image from System.Drawing.Image results in a vertical flip.
    The simplest patch I could see is to unflip it before copying data into the ZBar.Image buffer:

    using(Graphics g = Graphics.FromImage(bitmap)){
    g.PageUnit = GraphicsUnit.Pixel;
    g.DrawImageUnscaled(image, 0, 0);
    + bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
    }

    Thanks for the work on the wrapper!

    Comment by Giles — December 21, 2012 @ 9:06 pm

  34. @Giles,

    Thanks a lot… I’m quite surprised that the pixel array in BMP is upside down.

    I’ve applied your fix and pushed to http://github.com/jonasfj/zbar-sharp

    Again thanks, and Merry Christmas πŸ™‚

    Comment by jonasfj — December 22, 2012 @ 3:53 pm

  35. Hello Jonas,

    a big compliment, your code runs perfectly! … and it saved a lot of time for me!

    Best regards

    Stefan πŸ˜‰

    Comment by Stefan — February 13, 2013 @ 3:40 pm

  36. THE DOWNLOAD URL CAN NOT DOWN,
    it say
    There aren’t any uploads for this repository.

    Comment by SIMEN — July 4, 2013 @ 3:50 pm

  37. @Simen,
    I think the github downloads feature have been deprecated.
    In any event, just use the source from the git repository.

    I’ve updated the links to reflect these changes.

    Comment by jonasfj — July 4, 2013 @ 5:33 pm

  38. […] previously caused applications to crash at random. A thanks to the nameless commentor by the name thedarkking, who’s comment finally gave me a clue as to where the bug […]

    Pingback by Jonasfj.dk/blog — July 4, 2013 @ 5:35 pm

  39. Hi, thanks for this great work. I have got it working with building target x86 within Visual Studio. However, I have found that it doesn’t scan correctly as it goes pragmatically with quite a few images I am trying to scan. Then, for each of these images if I scan with the command line ZBarImg, the scan result was actually correct. Just wondering if you know the potential cause of the mismatching of the behaviour between the example you have got and the ZBarImg on the same image file used?

    Thanks for the help.

    Comment by Kevin — September 30, 2013 @ 2:34 am

  40. Just like to add that, at this stage I am scanning only PNG files and say I have done 2000 scans, all with similar layout as well, there would be 80% correct result and 20% no result. While with these no result image files, they can be scanned correct manually with ZBarImg.

    Comment by Kevin — September 30, 2013 @ 2:37 am

  41. From what I can see so far, you are using the zbar_scan_image while the ZBarImg is using the zbar_process_image. I will try to play with the files and see if I can get the zbar_process_image as an alternative in the project and see if the result would be improved from there.

    Comment by Kevin — September 30, 2013 @ 4:29 am

  42. Couldn’t work out the difference and get the same image scanned successfully as it would in ZBarImg….

    It seems to me that in ZBarIMG, it does the following
    ===================
    processor = zbar_processor_create(0);

    zbar_image_create
    zbar_image_set_format(zimage, *(unsigned long*)”Y800″);
    zbar_image_set_size(zimage, width, height);
    zbar_image_set_data(zimage, blob, bloblen, zbar_image_free_data);

    zbar_process_image(processor, zimage);
    ===================
    While in ZbarSharp example, when creating the ZImage, we have done a lot more
    Convert to RGB
    Set graphics
    MS save, seek, read

    Then we convert it back to Y800 again from one ZImage to anohter before processing
    ===================

    Do you think any of the image processing during the process may cause impact on the result?

    Comment by Kevin — September 30, 2013 @ 7:02 am

  43. @Kevin,
    As far as I can see from `zbar/processor.c` the zbar_processor* API calls are about synchronization…

    In particularly, `zbar_process_image` uses `zbar_scan_image` to scan for barcodes.

    I think the major difference is that zbarimg uses `MagickExportImagePixels` to do gray scale conversation.
    Whereas zbar-sharp uses `zbar_image_convert` which doesn’t use ImageMagick. I think I looked into different gray scale conversation algorithms, but this topic is non-trivial.

    So my guess is that `zbar_image_convert` is a fairly naive conversation algorithm, which would explain why zbarimg uses ImageMagick to do the image conversation. If you feel like implemented or using a better gray scale conversation algorithm, do submit a pull request πŸ™‚

    Note, you can test this hypothesis by converting your images to gray scale prior to scanning them with zbarimg and zbar-sharp…

    Comment by jonasfj — September 30, 2013 @ 9:34 am

  44. You are right
    ======
    The ImageScanner (C, C++) just scans each image and attaches the results to it
    The Processor (C, C++) builds on the ImageScanner to scan video or display scanned images in a window. This interface also offers an asynchronous callback mechanism for returning results.
    ======
    Processor uses Scan to do the work anyway.

    I was looking into this post
    http://stackoverflow.com/questions/7276212/reading-preserving-a-pixelformat-format48bpprgb-png-bitmap-in-net

    but so far there is no luck.

    I will try to build a ImageMagic for Windows and see if we can get ZBarImg accuracy. Will keep you posted.

    Comment by Kevin — September 30, 2013 @ 10:56 pm

  45. I end up doing
    first scan with ZXing, which is faster and covers 80% of the case
    then ZBar-Sharp integrated scan, which takes 3 times longer than ZXing but can significantly pick up ones ZXing couldn’t scan
    finally, i do a command line call to trigger ZBarImg for the ones failed top two, this takes double the time from ZBar-Sharp, but is executed only when top two fails.

    this setup I got almost 99.9% successful rate, with some performance benefit.

    Comment by Kevin — October 1, 2013 @ 11:15 pm

  46. That actually sounds like a reasonable approach… although it would probably be better to use http://magick.codeplex.com/ and do the high quality gray scale conversion in .Net before trying zbar-sharp.

    Comment by jonasfj — October 2, 2013 @ 4:34 pm

  47. I have tried it with modified Image/ImageScanner class but always get strange issues around PInvoke function. Will you have a chance to give it a try? I have however used the magic.net library to implement a few of my other requirements, so thanks for it anyway.

    Comment by Kevin — October 9, 2013 @ 4:09 am

  48. I’m not sure I have a working Windows VM for zbar-sharp development… But feel free to post the code on a gist or something. I can definitely take a quick look at it.

    By the way, why would you modify the Image/ImageScanner class(es).

    Comment by jonasfj — October 9, 2013 @ 4:43 am

  49. From my understanding, it seem that the Image class here that is doing the conversion and caused quality issue
    ==========
    public Image(System.Drawing.Image image) : this() {
    Byte[] data = new byte[image.Width * image.Height * 3];
    //Convert the image to RBG3
    using(Bitmap bitmap = new Bitmap(image.Width, image.Height, PixelFormat.Format24bppRgb)){
    using(Graphics g = Graphics.FromImage(bitmap)){
    g.PageUnit = GraphicsUnit.Pixel;
    g.DrawImageUnscaled(image, 0, 0);
    }
    // Vertically flip image as we are about to store it as BMP on a memory stream below
    // This way we don’t need to worry about BMP being upside-down when copying to byte array
    bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
    using(MemoryStream ms = new MemoryStream()){
    bitmap.Save(ms, ImageFormat.Bmp);
    ms.Seek(54, SeekOrigin.Begin);
    ms.Read(data, 0, data.Length);
    }
    }
    //Set the data
    this.Data = data;
    this.Width = (uint)image.Width;
    this.Height = (uint)image.Height;
    this.Format = FourCC(‘R’, ‘G’, ‘B’, ‘3’);
    }
    ==================
    In stead, I would like to be able to initiate an ZBar.Image with a file name as

    ==========
    public Image(string fileName)
    : this()
    {
    //Magic settings to set to GRAY
    MagicSettings settings = new MagicSettings() { colorspace = new colorspace.gray, density = new density(144,144) };
    //load with settings
    MagickImage image = new MagickImage(fileName, settings);

    //Set the data
    this.Data = image.ToByteArray();
    this.Width = (uint)image.Width;
    this.Height = (uint)image.Height;
    this.Format = FourCC(‘Y’, ‘8’, ‘0’, ‘0’);
    }
    ==============

    Or otherwise, what would be your approach to using ImageMagic.Net with ZBarSharp?

    Thanks for the inputs.

    Comment by Kevin — October 9, 2013 @ 9:47 pm

  50. bonjour aider moi a compiler et convert zbar en executable
    zbar-0.10 et merci.

    Comment by Rip — April 6, 2016 @ 2:30 am

  51. I added that zbar dll into my project, if i run the exe it shows exception On creating New ImageScanner Object,

    Exception:
    Could not load file or assembly ‘libzbar-cil

    How i can solve, I am using visual studio 2013 windows forms with c#

    Comment by Kanickairaj — September 26, 2018 @ 6:31 am

Leave a comment