我需要使用xamarin
从Android应用程序中的图库图像中读取条形码。
答案 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