Esempio n. 1
0
            public override void HandleMessage(Message msg)
            {
                if (msg.What == 100)
                {
                    Message msg1 = new Message();
                    msg1.What = 200;
                    msg1.Obj  = "";
                    try
                    {
                        YuvImage image = (YuvImage)msg.Obj;
                        if (image != null)
                        {
                            int[]        stridelist = image.GetStrides();
                            TextResult[] text       = barcodeReader.DecodeBuffer(image.GetYuvData(), previewWidth, previewHeight, stridelist[0], EnumImagePixelFormat.IpfNv21, "");
                            if (text != null && text.Length > 0)
                            {
                                for (int i = 0; i < text.Length; i++)
                                {
                                    if (i == 0)
                                    {
                                        msg1.Obj = "Code[1]: " + text[0].BarcodeText;
                                    }
                                    else
                                    {
                                        msg1.Obj = msg1.Obj + "\n\n" + "Code[" + (i + 1) + "]: " + text[i].BarcodeText;
                                    }
                                }
                            }
                        }
                    }
                    catch (BarcodeReaderException e)
                    {
                        msg1.Obj = "";
                        e.PrintStackTrace();
                    }

                    isReady = true;
                    myHandler.SendMessage(msg1);
                }
                else if (msg.What == 200)
                {
                    tv_text.Text = msg.Obj.ToString();
                    //System.Console.WriteLine("end update UI");
                }
            }
Esempio n. 2
0
        public void OnPreviewFrame(byte [] bytes, Android.Hardware.Camera camera)
        {
            if ((DateTime.Now - lastPreviewAnalysis).TotalMilliseconds < options.DelayBetweenAnalyzingFrames)
            {
                return;
            }

            try
            {
                var cameraParameters = camera.GetParameters();
                var img = new YuvImage(bytes, ImageFormatType.Nv21, cameraParameters.PreviewSize.Width, cameraParameters.PreviewSize.Height, null);

                if (barcodeReader == null)
                {
                    barcodeReader = new BarcodeReader(null, null, null, (p, w, h, f) =>
                                                      new PlanarYUVLuminanceSource(p, w, h, 0, 0, w, h, false));
                    //new PlanarYUVLuminanceSource(p, w, h, dataRect.Left, dataRect.Top, dataRect.Width(), dataRect.Height(), false))

                    if (this.options.TryHarder.HasValue)
                    {
                        barcodeReader.Options.TryHarder = this.options.TryHarder.Value;
                    }
                    if (this.options.PureBarcode.HasValue)
                    {
                        barcodeReader.Options.PureBarcode = this.options.PureBarcode.Value;
                    }
                    if (!string.IsNullOrEmpty(this.options.CharacterSet))
                    {
                        barcodeReader.Options.CharacterSet = this.options.CharacterSet;
                    }
                    if (this.options.TryInverted.HasValue)
                    {
                        barcodeReader.TryInverted = this.options.TryInverted.Value;
                    }

                    if (this.options.PossibleFormats != null && this.options.PossibleFormats.Count > 0)
                    {
                        barcodeReader.Options.PossibleFormats = new List <BarcodeFormat>();

                        foreach (var pf in this.options.PossibleFormats)
                        {
                            barcodeReader.Options.PossibleFormats.Add(pf);
                        }
                    }

                    //Always autorotate on android
                    barcodeReader.AutoRotate = true;
                }

                //Try and decode the result
                var result = barcodeReader.Decode(img.GetYuvData(), img.Width, img.Height, RGBLuminanceSource.BitmapFormat.Unknown);

                lastPreviewAnalysis = DateTime.Now;

                if (result == null || string.IsNullOrEmpty(result.Text))
                {
                    return;
                }

                Android.Util.Log.Debug("ZXing.Mobile", "Barcode Found: " + result.Text);

                ShutdownCamera();

                callback(result);
            } catch (ReaderException) {
                Android.Util.Log.Debug("ZXing.Mobile", "No barcode Found");
                // ignore this exception; it happens every time there is a failed scan
            } catch (Exception) {
                // TODO: this one is unexpected.. log or otherwise handle it
                throw;
            }
        }
Esempio n. 3
0
        private void EncodeMux()
        {
            int TIMEOUT_USEC = 10000;

            ByteBuffer[] encoderInputBuffers = _Encoder.GetInputBuffers();

            bool inputDone  = false;
            int  frameIndex = 0;

            try
            {
                while (true)
                {
                    if (!inputDone)
                    {
                        int inputBufIndex = _Encoder.DequeueInputBuffer(TIMEOUT_USEC);
                        if (inputBufIndex >= 0)
                        {
                            long ptsUsec = computePresentationTime(frameIndex);
                            if (frameIndex == _ByteBuffers.Count)
                            {
                                //  Send an empty frame with the end-of-stream flag set.  If we set EOS on a frame with data, that frame data will be ignored, and the output will be short one frame.
                                _Encoder.QueueInputBuffer(inputBufIndex, 0, 0, ptsUsec, MediaCodec.BufferFlagEndOfStream);
                                inputDone = true;
                                Log.Info(TAG, "sent input EOS (with zero-length frame)");
                            }
                            else
                            {
                                Log.Info(TAG, string.Format("Adding _ByteBuffers image index {0} to encoder", frameIndex));
                                ByteBuffer inputBuf  = encoderInputBuffers[inputBufIndex];
                                var        imagedata = _ByteBuffers[frameIndex];
                                int        chunkSize = 0;

                                if (imagedata == null)
                                {
                                    Log.Warn(TAG, string.Format("Adding _ByteBuffers image index {0} to encoder", frameIndex));
                                }
                                else
                                {
                                    //old way don't need to do this anymore.
                                    //Bitmap b = GetBitmap(imagedata);
                                    //byte[] yuv = new byte[b.Width * b.Height * 3 / 2];
                                    //int[] argb = new int[b.Width * b.Height];
                                    //b.GetPixels(argb, 0, b.Width, 0, 0, b.Width, b.Height);
                                    //encodeYUV420SP(yuv, argb, b.Width, b.Height);
                                    //b.Recycle();
                                    //old way don't need to do this anymore?

                                    //int[] argb = new int[imagedata.Width * imagedata.Height];
                                    //imagedata.GetPixels(argb, 0, imagedata.Width, 0, 0, imagedata.Width, imagedata.Height);
                                    //byte[] yuv = new byte[imagedata.Width * imagedata.Height * 3 / 2];
                                    //encodeYUV420SP(yuv, argb, imagedata.Width, imagedata.Height);
                                    //YuvImage yuv = GetYUVImage(imagedata);

                                    //byte[] decomB = Utils.DecompressFast(imagedata);

                                    //var yuv = new YuvImage(decomB, _CameraColorFormat, _Width, _Height, null);
                                    //Bitmap b = BitmapFactory.DecodeByteArray(imagedata, 0, imagedata.Length);
                                    //byte[] yuv = new byte[b.Width * b.Height * 3 / 2];
                                    //int[] argb = new int[b.Width * b.Height];
                                    //b.GetPixels(argb, 0, b.Width, 0, 0, b.Width, b.Height);
                                    //encodeYUV420SP(yuv, argb, b.Width, b.Height);

                                    Bitmap b    = BitmapFactory.DecodeByteArray(imagedata, 0, imagedata.Length);
                                    byte[] yuv  = new byte[b.Width * b.Height * 3 / 2];
                                    int[]  argb = new int[b.Width * b.Height];
                                    b.GetPixels(argb, 0, b.Width, 0, 0, b.Width, b.Height);
                                    encodeYUV420SP(yuv, argb, b.Width, b.Height);
                                    var yuvimage = new YuvImage(yuv, _CameraColorFormat, _Width, _Height, null);
                                    var yuvarray = yuvimage.GetYuvData();
                                    colorcorrection(ref yuvarray, b.Width, b.Height); //method for fixing common color matching issues see below for comments

                                    inputBuf.Put(yuvarray);

                                    chunkSize = yuvarray.Length;
                                    //yuv = null;
                                    //GC.Collect(); //essential to fix memory leak from new YuvImage allocation above
                                    b.Recycle();
                                }


                                //  the buffer should be sized to hold one full frame
                                inputBuf.Clear();
                                _Encoder.QueueInputBuffer(inputBufIndex, 0, chunkSize, ptsUsec, 0);
                                frameIndex++;
                            }
                        }
                        else
                        {
                            //  either all in use, or we timed out during initial setup
                            Log.Warn(TAG, "input buffer not available");
                        }
                    }

                    ByteBuffer[] encoderOutputBuffers = _Encoder.GetOutputBuffers();
                    var          mBufferInfo          = new MediaCodec.BufferInfo();

                    int encoderStatus = _Encoder.DequeueOutputBuffer(mBufferInfo, TIMEOUT_USEC);

                    if (encoderStatus == (int)MediaCodecInfoState.TryAgainLater)
                    {
                        Log.Info(TAG, "no output available, spinning to await EOS");
                    }
                    else if (encoderStatus == (int)MediaCodecInfoState.OutputBuffersChanged)
                    {
                        //  not expected for an encoder
                        Log.Warn(TAG, "not expected OutputBuffersChanged happened");
                        encoderOutputBuffers = _Encoder.GetOutputBuffers();
                    }
                    else if (encoderStatus == (int)MediaCodecInfoState.OutputFormatChanged)
                    {
                        //  should happen before receiving buffers, and should only happen once
                        if (_MuxerStarted)
                        {
                            Log.Error(TAG, "format changed twice and should never happen");
                            throw new RuntimeException("format changed twice");
                        }

                        MediaFormat newFormat = _Encoder.OutputFormat;

                        Log.Info(TAG, "format changed and starting MUX");
                        _TrackIndex = _Muxer.AddTrack(newFormat);
                        _Muxer.Start();
                        _MuxerStarted = true;
                    }
                    else if (encoderStatus < 0)
                    {
                        Log.Warn(TAG, "unexpected but lets ignore");
                        //  let's ignore it
                    }
                    else
                    {
                        ByteBuffer encodedData = encoderOutputBuffers[encoderStatus];
                        if (encodedData == null)
                        {
                            Log.Error(TAG, string.Format("encoderOutputBuffer {0} was null!!", encoderStatus));
                            throw new RuntimeException(string.Format("encoderOutputBuffer {0} was null!!", encoderStatus));
                        }

                        if ((mBufferInfo.Flags & MediaCodecBufferFlags.CodecConfig) != 0)
                        {
                            //  The codec config data was pulled out and fed to the muxer when we got
                            //  the INFO_OUTPUT_FORMAT_CHANGED status.  Ignore it.
                            mBufferInfo.Size = 0;
                        }

                        if (mBufferInfo.Size != 0)
                        {
                            if (!_MuxerStarted)
                            {
                                Log.Error(TAG, "muxer hasnt started!!");
                                throw new RuntimeException("muxer hasnt started");
                            }

                            //  adjust the ByteBuffer values to match BufferInfo (not needed?) old
                            //encodedData.Position(mBufferInfo.Offset);
                            //encodedData.Limit(mBufferInfo.Offset + this.mBufferInfo.Size);

                            _Muxer.WriteSampleData(_TrackIndex, encodedData, mBufferInfo);
                            Log.Info(TAG, string.Format("{0} bytes to muxer", mBufferInfo.Size));
                        }

                        _Encoder.ReleaseOutputBuffer(encoderStatus, false);
                        if ((mBufferInfo.Flags & MediaCodecBufferFlags.EndOfStream) != 0)
                        {
                            Log.Info(TAG, "End of Stream Reached!!");
                            break;
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Log.Error(TAG, "Decode or Muxer failed", e, e.Message);
                throw;
            }
        }
        public void OnPreviewFrame(byte [] bytes, Android.Hardware.Camera camera)
        {
            if ((DateTime.Now - lastPreviewAnalysis).TotalMilliseconds < options.DelayBetweenAnalyzingFrames)
            {
                return;
            }

            try
            {
                /* OLD Android Code
                 * //Fix for image not rotating on devices
                 * byte[] rotatedData = new byte[bytes.Length];
                 * for (int y = 0; y < height; y++) {
                 *  for (int x = 0; x < width; x++)
                 *      rotatedData[x * height + height - y - 1] = bytes[x + y * width];
                 * }
                 *
                 * var cameraParameters = camera.GetParameters();
                 *
                 * //Changed to using a YUV Image to get the byte data instead of manually working with it!
                 * var img = new YuvImage(rotatedData, ImageFormatType.Nv21, cameraParameters.PreviewSize.Width, cameraParameters.PreviewSize.Height, null);
                 * var dataRect = GetFramingRectInPreview();
                 *
                 * var luminance = new PlanarYUVLuminanceSource (img.GetYuvData(), width, height, dataRect.Left, dataRect.Top, dataRect.Width(), dataRect.Height(), false);
                 * //var luminance = new PlanarYUVLuminanceSource(img.GetYuvData(), cameraParameters.PreviewSize.Width, cameraParameters.PreviewSize.Height, 0, 0, cameraParameters.PreviewSize.Width, cameraParameters.PreviewSize.Height, false);
                 * var binarized = new BinaryBitmap (new ZXing.Common.HybridBinarizer(luminance));
                 * var result = reader.decodeWithState(binarized);
                 */



                var cameraParameters = camera.GetParameters();
                var img      = new YuvImage(bytes, ImageFormatType.Nv21, cameraParameters.PreviewSize.Width, cameraParameters.PreviewSize.Height, null);
                var dataRect = GetFramingRectInPreview();

                //var barcodeReader = new BarcodeReader(null, p => new PlanarYUVLuminanceSource(img.GetYuvData(), img.Width, img.Height, dataRect.Left, dataRect.Top,
                //                                            dataRect.Width(), dataRect.Height(), false), null, null)
                //{
                //	AutoRotate = true,
                //	TryHarder = true,
                //};

                var barcodeReader = new BarcodeReader(null, null, null, (p, w, h, f) =>
                                                      new PlanarYUVLuminanceSource(p, w, h, 0, 0, w, h, false))
                                    //new PlanarYUVLuminanceSource(p, w, h, dataRect.Left, dataRect.Top, dataRect.Width(), dataRect.Height(), false))
                {
                    AutoRotate = true,
                    TryHarder  = false
                };

                if (this.options.PureBarcode.HasValue && this.options.PureBarcode.Value)
                {
                    barcodeReader.PureBarcode = this.options.PureBarcode.Value;
                }

                if (this.options.PossibleFormats != null && this.options.PossibleFormats.Count > 0)
                {
                    barcodeReader.PossibleFormats = this.options.PossibleFormats;
                }

                var result = barcodeReader.Decode(img.GetYuvData(), img.Width, img.Height, RGBLuminanceSource.BitmapFormat.Unknown);


                lastPreviewAnalysis = DateTime.Now;

                if (result == null || string.IsNullOrEmpty(result.Text))
                {
                    return;
                }

                Android.Util.Log.Debug("ZXing.Mobile", "Barcode Found: " + result.Text);

                ShutdownCamera();

                activity.OnScan(result);
            } catch (ReaderException) {
                Android.Util.Log.Debug("ZXing.Mobile", "No barcode Found");
                // ignore this exception; it happens every time there is a failed scan
            } catch (Exception) {
                // TODO: this one is unexpected.. log or otherwise handle it

                throw;
            }
        }