1

I'm trying to use the EZTwain scanning library to retrieve barcodes from a scanned image, and I'm getting a return value of -4 when I try to call EZTwain.BARCODE_Recognize(IntPtr, int, int), which there is no description for in the EZTwain user guide.

In the EZTwain user guide, it lists some return values that are used as error codes as you can see here.

BARCODE_Recognize

int BARCODE_Recognize(HDIB hdib, int nMaxCount, int nType)
Find and recognize barcodes in the given image.
Don't look for more than nMaxCount barcodes (-1 means 'any number').
Expect barcodes of the specified type (-1 means 'any supported type')
You can add or 'or' together barcode types, to tell the recognizer to look for more
than one symbology. Return values:
   >0 n barcodes found
   0 no barcodes found
   -1 barcode services not available.
   -3 invalid or null image

There is no -4 return value listed, and I don't know where else to look because the user guide is the only thing that I know that is available for documentation on this library.

This is the code I'm using when I get the code of -4 returned.

I do call EZTwain_SetVendorKey but left that out for obvious reasons.

I'm wondering if it has something to do with the IntPtr I'm passing? The documentation says Call BARCODE_Recognize, passing it the handle of the image to search, the maximum number of barcode patches to find, and a mask of the barcode types (symbologies) to look for. If this function finds any barcodes, it returns a positive integer = the count of symbols (barcodes) found.

I pass the IntPtr i create using the image, and -1, -1 to find all barcodes in the image, using all of the barcode types.

public static string GetBarcode(Bitmap image, out BarcodeType barcodeType, int percentThatCanBeNonWhitish = 2, int pixelTolerance = 10)
{
  // initialize barcodeType to appease the compiler
  barcodeType = BarcodeType.NotBarcode;

  BitmapData bd = image.LockBits(new Rectangle(0, 0, image.Width, image.Height),
    ImageLockMode.ReadWrite,
    image.PixelFormat);

  List<string> barcodes = new List<string>();

  EZTwain.BARCODE_SelectEngine(EZTwain.EZBAR_ENGINE_DOSADI);
  EZTwain.BARCODE_SetDirectionFlags(EZTwain.EZBAR_HORIZONTAL | EZTwain.EZBAR_VERTICAL);

  IntPtr imgPtr = image.GetHbitmap();
  if (EZTwain.DIB_IsBlank(imgPtr, .002) == true)
  {
    // Do nothing, the page is blank
  }
  else if (EZTwain.BARCODE_IsEngineAvailable(EZTwain.EZBAR_ENGINE_DOSADI))
  {
    int count;
    count = EZTwain.BARCODE_Recognize(imgPtr, -1, -1);
    for (int i = 0; i < count; i++)
    {
        barcodes.Add(EZTwain.BARCODE_Text(i));
    }
  }

  if (barcodes.Count != 0)
  {
    string barcode = barcodes[0];
    // sets the type to coversheet if it is blank, else it uses ProcessBarcodeType()
    barcodeType = image.IsBlank(percentThatCanBeNonWhitish, pixelTolerance) ? BarcodeType.CoversheetBarcode : ProcessBarcodeType(barcode);
    return barcode;
  }
  else
  {
    return null;
  }
}

Does anyone know what this error code means? And if so, where did you discover what it meant?

Zack
  • 2,789
  • 33
  • 60

2 Answers2

2

Zack, you probably already figured this out. For future readers:

  1. There's a newer edition of the EZTwain toolkit, in which that -4 return code is documented. But, it just says "memory error (low memory?)" - still not very helpful in this case! Atalasoft makes the updated toolkit available on eztwain.com, and any valid EZTwain Pro 3 license will continue to work with those later 3.x versions of the toolkit.

  2. That image parameter EZTwain expects (pretty much everywhere in its API) is not just an 'image handle' but specifically and precisely an HDIB, which is a Global Handle to a block of memory containing a packed DIB = Device Independent Bitmap. These are all ancient things from the Win32 API, and only that specific combination is understandable to EZTwain. Don't be confused by seeing these represented as IntPtr's - IntPtr's can hold all kinds of different underlying native objects. I would guess that GetHBitmap does not return an HDIB, but an object that the old Windows API called an HBITMAP, which sounds confusingly similar and is completely non-interchangeable with an HDIB.

  3. EZTwain includes a number of functions for converting to and from other kinds of in-memory image formats, such as HBITMAP. I even think in recent editions of the toolkit, the eztwain.cs file has some functions that go to and from System.Drawing.Bitmap <==> HDIB (represented as System.IntPtr).

Spike0xff
  • 1,246
  • 1
  • 15
  • 24
  • 1- I think we have to stick with the 3.30 version for now, as we have another product that uses that version of the EZTwain library installed on the customer machines, and I'm not sure if we install the 3.43 version, that this product will continue to work. 2- I understand now what an IntPtr is. It is not any object type in particular, but rather just a pointer to the memory location. The method GetHBitmap says it returns a GDI Bitmap, but that is represented by an IntPtr, which I am able to pass to DIB_FromBitmap to get the HDIB eztwain wants when it recognizes barcodes. It works now anyway.. – Zack Aug 01 '13 at 15:02
  • 3- Page 49 here http://www.dosadi.com/pub/eztp/EZTwain_User_Guide.pdf, point 2 says "EZTwain can convert from DDB (HBITMAP) to DIB with DIB_FromBitmap." So we use GetHBitmap to get that HBITMAP pointer and pass it to BARCODE_Recognize. – Zack Aug 01 '13 at 15:11
  • 1
    Sounds right to me. Re upgrading: By design any later 3.x version of EZTwain should be a drop-in replacement for your 3.30 version. Of course for production deployment it's still responsible to test - first on one machine, then with each model of scanner if you use more than one. But we work hard to never break working customer code in a minor-version step. – Spike0xff Aug 07 '13 at 18:49
0

That error just means that there was some sort of unspecified memory error.

ascarb
  • 468
  • 5
  • 21