Search code examples
imagexamarinimage-processingxamarin.formszxing

How to merge two image in Xamarin Forms?


I'm developing a Xamarin Forms iOS app. In the xaml file, there is a grid.

<Grid x:Name="QrCodeSite" HeightRequest="300" Margin="37, 37, 37, 0">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
</Grid>

In the related .cs file, I use ZXing.Net.Mobile.Forms to generate a QR code and place it in the grid. And I put my logo in the same grid, which will finally appear at the center of the QR code.

var barcode = new ZXingBarcodeImageView
{
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand
};
barcode.BarcodeFormat = ZXing.BarcodeFormat.QR_CODE;
barcode.BarcodeOptions.Width = 650;
barcode.BarcodeOptions.Height = 650;
barcode.BarcodeOptions.Margin = 1;
barcode.BarcodeValue = value;


var img = new Image
{
Source = "logo.png",
WidthRequest = 70,
HeightRequest = 70,
VerticalOptions = LayoutOptions.Center,
HorizontalOptions = LayoutOptions.Center
};

QrCodeSite.Children.Clear();

QrCodeSite.Children.Add(barcode);
QrCodeSite.Children.Add(img);

The problem is, maybe my phone (iPhone 6s plus) is too slow, sometimes the logo appears first and after a lag (around 1 second) the QR code is shown. How can I merge the QR code and the logo into one image and then add it to the grid?


Solution

  • You can using SkiaSharp to display Image or merge images . Having a look at how to Display SkiaSharp bitmaps to download sample project to research at it.

    Based on Drawing on existing bitmaps reference , you can modify it as follow :

    public partial class MonkeyMoustachePage : ContentPage
    {
        SKBitmap monkeyBitmap;
    
        public MonkeyMoustachePage()
        {
            Title = "Monkey Moustache";
    
            monkeyBitmap = BitmapExtensions.LoadBitmapResource(GetType(),
                "SkiaSharpFormsDemos.Media.MonkeyFace.png");
    
            SKBitmap iconImage = BitmapExtensions.LoadBitmapResource(GetType(),
                "SkiaSharpFormsDemos.Media.GooglePlaylogo.png");
    
            int offset = monkeyBitmap.Width / 2 - iconImage.Width / 2;
            int offsetTop = monkeyBitmap.Height / 2 - iconImage.Height / 2;
            // Create canvas based on bitmap
            using (SKCanvas canvas = new SKCanvas(monkeyBitmap))
            {
                canvas.DrawBitmap(iconImage, SKRect.Create(offset, offsetTop, iconImage.Width, iconImage.Height));
            }
    
            // Create SKCanvasView to view result
            SKCanvasView canvasView = new SKCanvasView();
            canvasView.PaintSurface += OnCanvasViewPaintSurface;
            Content = canvasView;
    
            //save the new image
            using (MemoryStream memStream = new MemoryStream())
            using (SKManagedWStream wstream = new SKManagedWStream(memStream))
            {
                monkeyBitmap.Encode(wstream, imageFormat, quality);
                byte[] data = memStream.ToArray();
    
                // Check the data array for content!
    
                bool success = await DependencyService.Get<IPhotoLibrary>().SavePhotoAsync(data, folder, filename);
    
                // Check return value for success!
             }
        }
    
        void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
        {
            SKImageInfo info = args.Info;
            SKSurface surface = args.Surface;
            SKCanvas canvas = surface.Canvas;
    
            canvas.Clear();
            canvas.DrawBitmap(monkeyBitmap, info.Rect, BitmapStretch.Uniform);
        }
    }
    

    Then you will see a logo icon will display in original image :

    enter image description here

    If you want to save SkiaSharp bitmaps to files , have a look at this :https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/graphics/skiasharp/bitmaps/saving#exploring-the-image-formats

    Note: BitmapExtensions.cs file is from sample project .By the way , when adding image to project , you need to set Build ACtion of image be Embedded resource .As follow :

    enter image description here