从xamarin c#中读取Gallery Image中的条形码

时间:2017-02-26 03:11:04

标签: xamarin.android xamarin.forms

我需要使用xamarin从Android应用程序中的图库图像中读取条形码。

2 个答案:

答案 0 :(得分:0)

您需要读取图像文件然后解码它。

要对其进行解码,您可以使用此库Zxing。它有一个BarcodeReader类,其中包含decode方法。

<强> 更新

以下是我的表现:

使用上面的库,您需要在所有项目(Forms,Android和iOS)中安装它。

创建类以保存解码逻辑(在Forms Project中)

using System.Collections.Generic;
using ZXing;
using Xamarin.Forms;

namespace ReadBarcode
{
    public class BarcodeDecoding
    {
        IImageHelper _imageHelper;

        public BarcodeDecoding()
        {
            _imageHelper = DependencyService.Get<IImageHelper>();
        }


        public Result Decode(string file, BarcodeFormat? format = null, KeyValuePair<DecodeHintType, object>[] aditionalHints = null)
        {
            var r = GetReader(format, aditionalHints);

            var image = GetImage(file);

            var result = r.decode(image);

            return result;
        }

        MultiFormatReader GetReader(BarcodeFormat? format, KeyValuePair<DecodeHintType, object>[] aditionalHints)
        {
            var reader = new MultiFormatReader();

            var hints = new Dictionary<DecodeHintType, object>();

            if (format.HasValue)
            {
                hints.Add(DecodeHintType.POSSIBLE_FORMATS, new List<BarcodeFormat>() { format.Value });
            }
            if (aditionalHints != null)
            {
                foreach (var ah in aditionalHints) 
                {
                    hints.Add(ah.Key, ah.Value);
                }
            }

            reader.Hints = hints;

            return reader;
        }

        BinaryBitmap GetImage(string fileName) 
        {
            // Get image file and pass in the bytes array
            // or pass in the image name and load the image from the platform implementation.

            var byteArray = GetBytesArraysSomeWhere(fileName);

            var binaryBitmap = _imageHelper.GetBinaryBitmap(byteArray);

            return binaryBitmap;
        }
    }
}

我们需要在每个平台上进行一些处理,这就是我创建接口IImageHelper的原因,我们需要为每个平台实现一个实现。

public interface IImageHelper
{
    BinaryBitmap GetBinaryBitmap(byte[] image);

    BinaryBitmap GetBinaryBitmap(string imageName);
}

这样您就可以读取Forms项目中的图像并传入图像的字节数组表示,或者您可以传入图像名称并直接从平台特定的实现中读取它。

Bellow是上面界面的Android实现。对于此示例,我正在加载我添加到Android项目资源的文件。修改此内容以加载真实图像不会那么难,特别是如果您使用Xamarin Media plugin

[assembly: Xamarin.Forms.Dependency(typeof(ImageHelper))]
namespace ReadBarcode.Droid
{
    public class ImageHelper : IImageHelper
    {
        Context context;

        public ImageHelper()
        {
            context = Xamarin.Forms.Forms.Context;
        }

        public BinaryBitmap GetBinaryBitmap(string imageName)
        {
            throw new NotImplementedException();
        }

        public BinaryBitmap GetBinaryBitmap(byte[] image)
        {
            //uncomment the line below to use the image that is passed instead of a raw image.
            //Bitmap bitmap = BitmapFactory.DecodeByteArray(image, 0, image.Length);

            Bitmap bitmap = BitmapFactory.DecodeStream(context.Resources.OpenRawResource(Resource.Raw.static_qr_code_without_logo));
            byte[] rgbBytes = GetRgbBytes(bitmap);
            var bin = new HybridBinarizer(new RGBLuminanceSource(rgbBytes, bitmap.Width, bitmap.Height));
            var i = new BinaryBitmap(bin);

            return i;
        }

        private byte[] GetRgbBytes(Bitmap image)
        {
            var rgbBytes = new List<byte>();
            for (int y = 0; y < image.Height; y++)
            {
                for (int x = 0; x < image.Width; x++)
                {
                    var c = new Color(image.GetPixel(x, y));

                    rgbBytes.AddRange(new[] { c.R, c.G, c.B });
                }
            }
            return rgbBytes.ToArray();
        }

现在您已经拥有了所需的一切,只需将页面设置为调用BarcodeDecoding类的Decode方法即可。

我的代码背后是这样的:

public partial class ReadBarcodePage : ContentPage
{
    BarcodeDecoding barcode;

    public ReadBarcodePage()
    {
        barcode = new BarcodeDecoding();

        InitializeComponent();
    }

    void Handle_Clicked(object sender, System.EventArgs e)
    {
        var aditionalHints = new KeyValuePair<DecodeHintType, object>(key: DecodeHintType.PURE_BARCODE, value: "TRUE");

        var result = barcode.Decode(file: "image_to_read", format: BarcodeFormat.QR_CODE, aditionalHints: new [] {aditionalHints } );

        //Label to show the text decoded
        QrResult.Text = result.Text;
    }
}

注意:我使用的是BarcodeFormat.QR_CODE,因为这是我创建的条形码类型。如果您使用不同的东西,只需从枚举中选择它。

希望这有帮助。

您可以找到完整的示例here

here使用的代码。

答案 1 :(得分:0)

Zxing是强大的,我也是这样做的,但是我想补充一下,我偶尔会遇到一个带有图像分辨率的BarcodeReader.Decode问题,该问题会在物理上出现的条形码上发现近乎未命中的空值。

在弄乱了一些小提琴之后,我发现你可以通过以下代码改变高度/宽度比,并且经常在Decode返回null之前获得好的结果:

SplitViewController