Search code examples
androidxamarinbitmapxamarin.formszxing

How to set size of the bitmap in ZXing?


I am using ZXing to generate a QR code. This is what my code looks like:

public partial class QRPage : ContentPage
{
    public QRPage()
    {
        InitializeComponent();


        var stream = DependencyService.Get<IBarcodeService>().ConvertImageStream("nika");
        qrImage.Source = ImageSource.FromStream(() => { return stream; });
        qrImage.HeightRequest = 200;
        
    }
}

And the other part:

[assembly: Xamarin.Forms.Dependency(typeof(BarcodeService))]
namespace MyApp.Droid
{
    public class BarcodeService : IBarcodeService
    {
        public Stream ConvertImageStream(string text, int width = 500, int height = 500)
        {
            var barcodeWriter = new ZXing.Mobile.BarcodeWriter
            {
                Format = ZXing.BarcodeFormat.QR_CODE,
                Options = new ZXing.Common.EncodingOptions
                {
                    Width = width,
                    Height = height,
                    Margin = 2
                }
            };

            barcodeWriter.Renderer = new ZXing.Mobile.BitmapRenderer();
            var bitmap = barcodeWriter.Write(text);
            var stream = new MemoryStream();
            bitmap.Compress(Bitmap.CompressFormat.Jpeg, 100, stream);
            stream.Position = 0;
            return stream;
        }
    }
}

Here is the xaml where I'm using the code:

<StackLayout Padding="20,30,20,30">
    <Label Text="..." FontSize="Medium "/>
    <Frame VerticalOptions="CenterAndExpand">
      <Image x:Name="qrImage" WidthRequest="300" />
    </Frame>
    ...
</StackLayout>

The problem is, that no matter what do I set as height and width for ConvertImageStream, the resulting image is not square, but rather looks like this:

enter image description here

How can I turn it into a square? Thanks in advance.


Solution

  • Your code is correct and the image correctly sized:

    enter image description here

    I doubled checked by saving it:

    var filePath = System.IO.Path.Combine(Environment.ExternalStorageDirectory.AbsolutePath, "qrcode.png");
    using (var fileStream = new FileStream(filePath, FileMode.Create))
    {
        bitmap.Compress(Bitmap.CompressFormat.Png, 100, fileStream);
    }
    

    And then pulling it and checking its size:

    $ adb pull /sdcard/qrcode.png
    [100%] /sdcard/qrcode.png
    $ identify qrcode.png
    qrcode.png PNG 500x500 500x500+0+0 8-bit sRGB 2.85KB 0.000u 0:00.000
    

    My Page code:

    var image = new Image();
    var content = new ContentPage
    {
        BackgroundColor = Color.Red,
        Title = "ZXingQRCode",
        Content = new StackLayout
        {
            VerticalOptions = LayoutOptions.Center,
            Children = {
                new Label {
                    HorizontalTextAlignment = TextAlignment.Center,
                    Text = "StackOverflow",
                    FontSize = 40
                },
                image
            }
        }
    };
    MainPage = new NavigationPage(content);
    var stream = DependencyService.Get<IBarcodeService>().ConvertImageStream("https://StackOverflow.com");
    image.Source = ImageSource.FromStream(() => { return stream; });
    image.HeightRequest = 250;
    

    Update:

    It is the Frame that you are seeing that is wider then the image, not the image itself. Change the BackgroundColor of the Frame

    <StackLayout Padding="20,30,20,30">
        <Label Text="..." FontSize="Medium" />
        <Frame VerticalOptions="CenterAndExpand" BackgroundColor="Red">
            <Image x:Name="qrImage" WidthRequest="300" />
        </Frame>
    </StackLayout>
    

    enter image description here