private void Worker()
        {
            float fY1;
                float fY2;

                float scale;

                // calculate picFrame just once
                if (picFrame == RectangleF.Empty)
                {

                    // check if device has retina display, if so scale factor by 2
                    if (UIScreen.MainScreen.RespondsToSelector(new MonoTouch.ObjCRuntime.Selector(@"scale")) &&
                        UIScreen.MainScreen.Scale == 2)
                        scale = 2f;
                    else
                        scale = 1f;

                    // check if the device is an ipad or an iphone
                    if (UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Phone)
                    {
                        fY1 = 146f / UIScreen.MainScreen.Bounds.Height * scale;
                        fY2 = 157f / UIScreen.MainScreen.Bounds.Height * scale;
                    }
                    else
                    {
                        // ipad - constants probably need to be modified if running at native screen res

                        fY1 = 146f / UIScreen.MainScreen.Bounds.Height * scale;
                        fY2 = 157f / UIScreen.MainScreen.Bounds.Height * scale;
                    }

                    picFrame = new RectangleF(0, UIScreen.MainScreen.Bounds.Height * fY1, UIScreen.MainScreen.Bounds.Width * scale, UIScreen.MainScreen.Bounds.Height * fY2);
                }

                if(hints==null)
                {
                    var list = new ArrayList();
                    list.Add(com.google.zxing.BarcodeFormat.EAN_8);
                    list.Add(com.google.zxing.BarcodeFormat.EAN_13);

                    hints = new Hashtable();
                    hints.Add(com.google.zxing.DecodeHintType.POSSIBLE_FORMATS, list);
                    hints.Add(com.google.zxing.DecodeHintType.NEED_RESULT_POINT_CALLBACK, new ResultCallBack(this));
                }

                if(_multiFormatOneDReader == null)
                {
                    _multiFormatOneDReader = new com.google.zxing.oned.MultiFormatOneDReader(hints);
                }

                // Capturing screen image
                using (var screenImage = CGImage.ScreenImage.WithImageInRect(picFrame))
                {
                    _theScreenImage = UIImage.FromImage(screenImage);
                    Bitmap srcbitmap = new System.Drawing.Bitmap(_theScreenImage);
                    LuminanceSource source = null;
                    BinaryBitmap bitmap = null;
                    try {
                        source = new RGBLuminanceSource(srcbitmap, screenImage.Width, screenImage.Height);
                      	bitmap = new BinaryBitmap(new HybridBinarizer(source));

                        com.google.zxing.common.BitArray row = new com.google.zxing.common.BitArray(screenImage.Width);
                        int middle = screenImage.Height >> 1;
                        int rowStep = System.Math.Max(1, screenImage.Height >> (4));

                        for (int x = 0; x < 9; x++)
                        {

                            // Scanning from the middle out. Determine which row we're looking at next:
                            int rowStepsAboveOrBelow = (x + 1) >> 1;
                            bool isAbove = (x & 0x01) == 0; // i.e. is x even?
                            int rowNumber = middle + rowStep * (isAbove?rowStepsAboveOrBelow:- rowStepsAboveOrBelow);
                            if (rowNumber < 0 || rowNumber >= screenImage.Height)
                            {
                                // Oops, if we run off the top or bottom, stop
                                break;
                            }

                            // Estimate black point for this row and load it:
                            try
                            {
                                row = bitmap.getBlackRow(rowNumber, row);

                                var resultb = _multiFormatOneDReader.decodeRow(rowNumber, row, hints);
                                if(resultb.Text!=null)
                                {
                                    BeepOrVibrate();
                                    _parentViewController.BarCodeScanned(resultb);

                                    break;
                                }
                                else {
                                    continue;
                                }

                            }
                            catch (ReaderException re)
                            {
                                continue;
                            }

                        }

            //					var result = _barcodeReader.decodeWithState(bitmap);
            //
            //					if(result.Text!=null)
            //					{
            //						_multiFormatOneDReader = null;
            //						BeepOrVibrate();
            //						_parentViewController.BarCodeScanned(result);
            //					}

                    } catch (Exception ex) {
                        Console.WriteLine(ex.Message);
                    }
                    finally {
                        if(bitmap!=null)
                            bitmap = null;

                         if(source!=null)
                            source = null;

                        if(srcbitmap!=null)
                            srcbitmap = null;

                    }

                }
        }
        private void Worker()
        {
            //iphone 4 : 960 x 640
                //iphone 3 : 320 x 480
                if(DeviceHardware.Version == DeviceHardware.HardwareVersion.iPhone4)
                {
                    picFrame = new RectangleF(0, 146*2, 320*2, 157*2);
                }

                if(hints==null)
                {
                    var list = new ArrayList();
                    list.Add(com.google.zxing.BarcodeFormat.EAN_8);
                    list.Add(com.google.zxing.BarcodeFormat.EAN_13);

                    hints = new Hashtable();
                    hints.Add(com.google.zxing.DecodeHintType.POSSIBLE_FORMATS, list);
                    hints.Add(com.google.zxing.DecodeHintType.NEED_RESULT_POINT_CALLBACK, new ResultCallBack(this));
                }

                if(_multiFormatOneDReader == null)
                {
                    _multiFormatOneDReader = new com.google.zxing.oned.MultiFormatOneDReader(hints);
                }

                // Capturing screen image
                using (var screenImage = CGImage.ScreenImage.WithImageInRect(picFrame))
                {
                    _theScreenImage = UIImage.FromImage(screenImage);
                    Bitmap srcbitmap = new System.Drawing.Bitmap(_theScreenImage);
                    LuminanceSource source = null;
                    BinaryBitmap bitmap = null;
                    try {
                        source = new RGBLuminanceSource(srcbitmap, screenImage.Width, screenImage.Height);
                      	bitmap = new BinaryBitmap(new HybridBinarizer(source));

                        com.google.zxing.common.BitArray row = new com.google.zxing.common.BitArray(screenImage.Width);
                        int middle = screenImage.Height >> 1;
                        int rowStep = System.Math.Max(1, screenImage.Height >> (4));

                        for (int x = 0; x < 9; x++)
                        {

                            // Scanning from the middle out. Determine which row we're looking at next:
                            int rowStepsAboveOrBelow = (x + 1) >> 1;
                            bool isAbove = (x & 0x01) == 0; // i.e. is x even?
                            int rowNumber = middle + rowStep * (isAbove?rowStepsAboveOrBelow:- rowStepsAboveOrBelow);
                            if (rowNumber < 0 || rowNumber >= screenImage.Height)
                            {
                                // Oops, if we run off the top or bottom, stop
                                break;
                            }

                            // Estimate black point for this row and load it:
                            try
                            {
                                row = bitmap.getBlackRow(rowNumber, row);

                                var resultb = _multiFormatOneDReader.decodeRow(rowNumber, row, hints);
                                if(resultb.Text!=null)
                                {
                                    BeepOrVibrate();
                                    _parentViewController.BarCodeScanned(resultb);

                                    break;
                                }
                                else {
                                    continue;
                                }

                            }
                            catch (ReaderException re)
                            {
                                continue;
                            }

                        }

            //					var result = _barcodeReader.decodeWithState(bitmap);
            //
            //					if(result.Text!=null)
            //					{
            //						_multiFormatOneDReader = null;
            //						BeepOrVibrate();
            //						_parentViewController.BarCodeScanned(result);
            //					}

                    } catch (Exception ex) {
                        Console.WriteLine(ex.Message);
                    }
                    finally {
                        if(bitmap!=null)
                            bitmap = null;

                         if(source!=null)
                            source = null;

                        if(srcbitmap!=null)
                            srcbitmap = null;

                    }

                }
        }