Open meJevin opened 3 years ago
Hello @meJevin, Did you find a way to decode from an image file ?
@SylvainMoingeon, yes.
My solution was the following:
I am now picking a photo and getting its FullPath
, which I pass into my aforementioned service.
In iOS and Android implementations it's easy to get pixel data of images when you have a file path. So I just convert the pixel data from the selected photo into a LuminanceSource
and decode it using a BarcodeReader
If this can help, here is iOS and Android implementation with latest version (3.1.0-beta2) Maybe @meJevin has a better implementation to provide ?
On forms project :
var selectedPhoto = await Xamarin.Essentials.MediaPicker.PickPhotoAsync();
if (selectedPhoto == null)
return;
string decodedText = DependencyService.Get<IZXingService>().Decode(selectedPhoto.FullPath);
IZXingService :
public interface IZXingService
{
string Decode(string filePath);
}
On iOS :
public string Decode(string filePath)
{
var reader = new UIImageBarcodeReader();
var image = UIImage.FromFile(filePath);
var result = reader.Decode(image);
if (result != null)
{
return result.Text;
}
else
{
// handle as you want
}
}
On Android :
public string Decode(string filePath)
{
Bitmap bitmap = BitmapFactory.DecodeFile(filePath);
byte[] rgbBytes = GetRgbBytes(bitmap);
var bin = new HybridBinarizer(new RGBLuminanceSource(rgbBytes, bitmap.Width, bitmap.Height));
var i = new BinaryBitmap(bin);
var reader = new MultiFormatReader();
var result = reader.decode(i);
if (result != null)
{
return result.Text;
}
else
{
// handle as you want
}
}
private static 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 Android.Graphics.Color(image.GetPixel(x, y));
rgbBytes.AddRange(new[] { c.R, c.G, c.B });
}
}
return rgbBytes.ToArray();
}
@SylvainMoingeon my solution is pretty much the same :)
@meJevin @SylvainMoingeon Dropping this here for anyone who needs a UWP solution
public async Task<string> DecodeAsync(string filePath)
{
var file = await StorageFile.GetFileFromPathAsync(filePath);
//QR code conversion from jpeg and return string.
SoftwareBitmap softwareBitmap;
using (IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read))
{
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(fileStream);
softwareBitmap = await decoder.GetSoftwareBitmapAsync();
}
// create a barcode reader instance
var barcodeReader = new BarcodeReader
{
AutoRotate = true,
Options = { TryHarder = true }
};
Result result = barcodeReader.Decode(softwareBitmap);
// do something with the result
if (result != null)
{
return result.Text;
}
return null;
}
Using Xamarin.Essentials I let the user pick a photo and try to decode its bytes like so:
But I'm getting a null error when hitting the Decode line.
How would one implement the functionality I'm going for?