Search code examples
xamarinxamarin.iosvisual-studio-2017zxingzbar

cannot convert from UIKit.UIImage to ZXing.LuminanceSource - Xamarin iOS in Visual Studios 2017


All the examples I see are for Xamarin Forms, nothing for Xamarin for Visual Studios. I have an iOS app I'm developing with Xamarin for Visual Studio and need to read barcodes. I downloaded ZBar into Visual Studio 2017 from NuGet and installed it, no problem there. I access the camera and capture an image (barcode), no problem. However, there seems to be no way to convert the UIKit.UIIMage captured from the camera to a "ZXing.LuminanceSource" so it can be decoded. If someone could help point me in the right direction I would appreciate it. The code I have is fairly simple taken from the ZBar example included with the download:

IBarcodeReader scanPage = new BarcodeReader();

var result = scanPage.Decode(theImage); // the image is public and is set to the image returned by the camera.  It's here I get the error in intellisense "cannot convert from UIKit.UIImage to ZXing.LuminanceSource"

Camera image return code:

    [Foundation.Export("imagePickerController:didFinishPickingImage:editingInfo:")]
    public void FinishedPickingImage(UIKit.UIImagePickerController picker, UIKit.UIImage image, Foundation.NSDictionary editingInfo)
    {
        theImage = MaxResizeImage(image, 540f, 960f);
        picker.DismissModalViewController(false);

    }

    [Foundation.Export("imagePickerControllerDidCancel:")]
    public void Canceled(UIKit.UIImagePickerController picker)
    {
        DismissViewController(true, null);
    }

    public static UIImage MaxResizeImage(UIImage sourceImage, float maxWidth, float maxHeight)
    {
        var sourceSize = sourceImage.Size;
        var maxResizeFactor = Math.Min(maxWidth / sourceSize.Width, maxHeight / sourceSize.Height);
        if (maxResizeFactor > 1) return sourceImage;
        var width = maxResizeFactor * sourceSize.Width;
        var height = maxResizeFactor * sourceSize.Height;
        UIGraphics.BeginImageContext(new CGSize((nfloat)width, (nfloat)height));
        sourceImage.Draw(new CGRect(0, 0, (nfloat)width, (nfloat)height));
        var resultImage = UIGraphics.GetImageFromCurrentImageContext();
        UIGraphics.EndImageContext();
        return resultImage;
    }

}

Solution

  • I managed to resolve the issue with some help from @Jason, thanks Jason. I downloaded from NuGet and installed ZXing.Net.Mobile AND ZXing.Net.Mobile.Forms. You need both for Xamarin - Visual Studios. Removed all that camera code and replaced with 3 lines of code, plus I needed to add async to my button_TouchUpInside call.

    In AppDelegate FinishedLaunching:

        public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
        {
            // Override point for customization after application launch.
            // If not required for your application you can safely delete this method
    
            // Add this line to initialize ZXing
    
            ZXing.Net.Mobile.Forms.iOS.Platform.Init();
    
            return true;
        }
    

    Changed the button code to this, make button async to await scan result:

        async partial void ScanBarCode_TouchUpInside(UIButton sender)
        {
           // Create scanner
            var scanner = new ZXing.Mobile.MobileBarcodeScanner();
    
            // Store result of scan in var result, need to await scan
            var result = await scanner.Scan();
    
            // display bar code number in text field
            Textbox_BarCode.Text = result.Text;
        }
    

    Works every time (thus far).