QR Code Generate... create image... send as attachment...

Stewart Basterash 96 Reputation points
2023-09-11T20:37:47.2366667+00:00

I have an existing Xamarin Forms App for Android only. A report function uses the Xamarin Community Toolkit "email" feature. The body of the email is a culmination of data. An end user request was to add a QR code with a piece of that data. I have installed ZXing component and am generating the onscreen barcode... all of this works fine. I need some assistance on how to add the qr code to the email as an attachment.

Can anyone provide some help in this area. I have attempted several approaches, but ZXing.Net.Mobile doesn't have a very straightforward way to do this... or the documentation is unclear.

Xamarin
Xamarin
A Microsoft open-source app platform for building Android and iOS apps with .NET and C#.
5,283 questions
{count} votes

2 answers

Sort by: Most helpful
  1. Leon Lu (Shanghai Wicresoft Co,.Ltd.) 67,446 Reputation points Microsoft Vendor
    2023-09-13T08:46:44.8066667+00:00

    Hello,

    but I am having difficulty converting that to an image file for saving as a .bmp, .jpg to attach. The problem seems to be that most of the components that use .NET are using a different System.Drawing namespace and these throw errors in Xamarin Forms.

    You cannot convert ImageSource to an image file, however, here is a workaround, you can show this Image control fullscreen, then you can take a screenshot. Then save this image to app folder like following code. I use a button click event for testing.

    string targetFile;
    private async void Button_Clicked(object sender, EventArgs e)
    {
        var screenshot = await Screenshot.CaptureAsync();
        Stream stream = await screenshot.OpenReadAsync();
    
       // Create an output filename
        targetFile = Path.Combine(FileSystem.AppDataDirectory, "QRcode.jpg");
        // Copy the file to the AppDataDirectory
         FileStream outputStream = File.Create(targetFile);
        await stream.CopyToAsync(outputStream);
        stream.Close();
        outputStream.Close();   
    }
    

    Next, you can send email by this QRCode image.

    private async void Button_Clicked_1(object sender, EventArgs e)
    {
        
             var message = new EmailMessage
             {
                 Subject = "Hello",
                 Body = "World",
             };
             message.Attachments.Add(new EmailAttachment(targetFile));
             await Email.ComposeAsync(message);
    }
    

    Best Regards,

    Leon Lu


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


  2. Stewart Basterash 81 Reputation points
    2023-09-14T11:18:27.5633333+00:00

    After many days of testing I have discovered one path that worked for me. I did not attempt every itteration but I was glad to be able to move on from this issue.

    QRCoder has a number of "renderers". Some work on the Android platform, others do not. This is the code that finally worked for me.

    For onscreen QRCode Images this worked in Xamarin Forms:

    QRCodeGenerator qrGenerator = new QRCodeGenerator();
    QRCodeData qrCodeData = qrGenerator.CreateQrCode(QRCodeString, QRCodeGenerator.ECCLevel.Q);
    PngByteQRCode qrCode = new PngByteQRCode(qrCodeData);
    QRCodeByteArray = qrCode.GetGraphic(QRPixels);
    QRCodeImage.Source = ImageSource.FromStream(() => new MemoryStream(QRCodeByteArray));
    

    The first two lines create the generator and are very standard across all. The third line of code creates a PNG byte array renderer. The array can be used in two ways. A byte array that can be streamed as a datasource, or a byte array that can be used to writer to a file on disk. I would have rather streamed the byte array directly in to an Email Message Attachment but using Xamarin Forms Community Toolkit the Email Message Attachment only allows using a file unlike a standard SMTP email attachment where it allows streaming an attachment.

    To create the PNG file for attachment the code is virtually the same except I use the byte array and steam it to a file with the file name having a .png extension. line #4 above "QRCodeByteArray" is stored in my view model so I can refer to it when I require the attachment to be created. In this way I do not have to recreate the generator, or recreate the byte array. The byte array generated above is used in line two using statement. I then am ready to call the email compose.

    var qrAttachmentFileName = Path.Combine(FileSystem.CacheDirectory, onDiskFileName);
    using (var stream = new MemoryStream(QRCodeByteArray))
    using (var newStream = File.OpenWrite(qrAttachmentFileName))
        await stream.CopyToAsync(newStream);