Azure Functions and Cloud QRCoder

Generating QR CodePhoto from Pexels

Originally Posted On: https://medium.com/@ahmed.it.hmoud/azure-functions-cloud-qrcoder-6d9a02982984

Generate QR Code Using Azure Functions and QRCoder and IronBarcode Libraries

In this short blog, I will explain how to generate QR code using Azure Functions and the popular QRCoder library. I will also explained how to save the generated blob to Azure blob storage so you avoid generating the QR every time you need to use it.

Pre-requests for this tutorial

  1. An active Azure subscription
  2. .NET 8
  3. Visual Studio or VS code
  4. Azure Functions Core Tools and Azure CLI

Creating the necessary resources

Let’s create a simple HTTP trigger locally by following the below steps:

  • Create a new a folder on your file-system named C:CodeAzureFunctionsv4DotNetQRCoder.
  • Create a new function using the func new command, select HttpTrigger as the trigger type and name it GenerateQR.

Press enter or click to view image in full size

Press enter or click to view image in full size

Press enter or click to view image in full size

Press enter or click to view image in full size

Changing the C# code to read the input string and generate QR code

using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Logging;
using QRCoder;
using System.Net;

namespace QRCodeGeneration
{
    public class QRGenerator
    {
        private readonly ILogger<QRGenerator> _logger;

        public QRGenerator(ILogger<QRGenerator> logger)
        {
            _logger = logger;
        }

        [Function("GenerateQR")]
        public async Task<HttpResponseData> Run(
        [HttpTrigger(AuthorizationLevel.Function, "get", "post")]
          HttpRequestData req, [FromQuery] string text)
        {
            _logger.LogInformation("Starting GenerateQR function.");

            // Read the text to generate QR image from the GET query string 'text' parameter
            
            // If the text was not provided, return 400 response with a descriptive message
            if (string.IsNullOrWhiteSpace(text))
            {
                HttpResponseData? badRequestResponse = req.CreateResponse(HttpStatusCode.BadRequest);

                await badRequestResponse.WriteStringAsync("You should provide query string named text or a request body to generate a QR code");

                return badRequestResponse;
            }

            // Prepare the HTTP response of the image
            HttpResponseData? imageResponse = req.CreateResponse(HttpStatusCode.OK);

            // Generate the QR code and write it to the response body asynchronously
            using (QRCodeGenerator qrGenerator = new QRCodeGenerator())
            using (QRCodeData qrCodeData = qrGenerator.CreateQrCode(text, QRCodeGenerator.ECCLevel.Q))
            using (PngByteQRCode qrCode = new PngByteQRCode(qrCodeData))
            {
                byte[] qrCodeImage = qrCode.GetGraphic(20);
                // Generated image will be of type png
                imageResponse.Headers.Add("Content-Type", "image/png");
                await imageResponse.Body.WriteAsync(qrCodeImage, 0, qrCodeImage.Length);
            }

            _logger.LogInformation($"Starting GenerateQR generated a QR code for text {text}.");

            return imageResponse;
        }
    }
}

Testing the app

  • Run the application in Visual Studio (CTRL + F5)

Press enter or click to view image in full size

  • Run the provided URL in a Web browser with no data provided, you are expected to get 400 Bad Request.

Press enter or click to view image in full size

  • Run the same with a query string parameter ‘text’, you will get the QR code for it

Press enter or click to view image in full size

  • Scanning the QR using my mobile phone, I can see the QR text or navigate to the provided URL

Press enter or click to view image in full size

Saving the generated QR code to Azure Storage

We can use Azure Storage to store the generated QR code for to reasons:

  • Saving the generated QR code and share the blob URL with any other service or show it in your application.
  • Avoid calling the function every time you want to get the same QR code.

Changes to the application code

  • Open Visual Studio NuGet package manager and install storage extension.

Press enter or click to view image in full size

  • Include the below using statement in QRGenerator.cs
using Azure.Storage.Blobs.Specialized;
  • Change the function code as below
[Function("GenerateQR")]
public async Task<HttpResponseData> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req,
[FromQuery] string text,
[BlobInput("qr-codes/{text}.png")] BlockBlobClient inputQRCode,
[BlobInput("qr-codes/{text}.png")] BlockBlobClient outputQRCode)
{
    _logger.LogInformation("Starting GenerateQR function.");

    // If the text was not provided, return 400 response with a descriptive message
    if (string.IsNullOrWhiteSpace(text))
    {
        HttpResponseData? badRequestResponse = req.CreateResponse(HttpStatusCode.BadRequest);

        await badRequestResponse.WriteStringAsync("You should provide a request body to generate a QR code, example: {"text": "https://www.bing.com"}.");

        return badRequestResponse;
    }

    byte[]? qrCodeImage = null;
    var qrImageResponse = req.CreateResponse(HttpStatusCode.OK);
    qrImageResponse.Headers.Add("Content-Type", "image/png");
    
    // Check if the blob exists in the storage and store the content in a byte array
    if (await inputQRCode.ExistsAsync())
    {
        using (var ms = new MemoryStream())
        {
            inputQRCode.DownloadTo(ms);
            qrCodeImage = ms.ToArray();
        }
    }
    else
    {
        // If the file was not found in blob storage, generate a new on using QRCoder and save to to Azure Storage
        using (QRCodeGenerator qrGenerator = new QRCodeGenerator())
        using (QRCodeData qrCodeData = qrGenerator.CreateQrCode(text, QRCodeGenerator.ECCLevel.Q))
        using (PngByteQRCode qrCode = new PngByteQRCode(qrCodeData))
        {
            qrCodeImage = qrCode.GetGraphic(20);

            using (var ms = new MemoryStream(qrCodeImage, false))
            {
                await outputQRCode.UploadAsync(ms);
            }

        }
    }

    await qrImageResponse.Body.WriteAsync(qrCodeImage!, 0, qrCodeImage!.Length);

    _logger.LogInformation($"Generate QR function generated a QR code for text {text}.");

    return qrImageResponse;
}

. Testing the results in a web browser, you are expected to get the QR code and a new blob will be generated in the storage container “qr-codes”.

Press enter or click to view image in full size

Press enter or click to view image in full size

You can generate a SAS token for the blob to share it with someone or within another app.

Press enter or click to view image in full size

I changed the SAS expiration date to be after a few years, generally it’s better generating SAS with short expiry time.

Press enter or click to view image in full size

If your Azure Function needs to handle more than just QR codes, the Iron Suite provides a broader barcode toolkit. IronBarcode supports QR codes alongside 30+ other barcode formats like Code 128, PDF417, and Data Matrix within a single library.

More on IronBarcode will be explained in a future article, you can include it in your .NET project using NuGet package manager:

https://www.nuget.org/packages/barcode

The below code snippet shows you an IronBarcode C# implementation:

using IronBarCode;

// Generate QR code
var qrCode = BarcodeWriter.CreateBarcode(text, BarcodeEncoding.QRCode);
qrCode.SetMargins(10);
byte[] qrCodeImage = qrCode.ToPngBinaryData();

// Or read barcodes from uploaded images
var results = BarcodeReader.Read("uploaded-image.png");
foreach (var barcode in results)
{
    Console.WriteLine($"Type: {barcode.BarcodeType}, Value: {barcode.Value}");
}

The library also handles barcode reading, which pairs well with your blob storage caching approach. You could extend the function to both generate and decode QR codes from the same endpoint. For functions that also need to embed QR codes into PDF documents, IronPDF integrates directly with IronBarcode to stamp barcodes onto generated PDFs.

The Azure Function code implementation can be slightly changed to use IronBarcode.

        [Function("GenerateIronQR")]
        public async Task<HttpResponseData> Run(
        [HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req,
        [FromQuery] string text,
        [BlobInput("qr-codes/{text}.png")] BlockBlobClient inputQRCode,
        [BlobInput("qr-codes/{text}.png")] BlockBlobClient outputQRCode
            )
        {
            _logger.LogInformation("Starting GenerateQR function.");

            // If the text was not provided, return 400 response with a descriptive message
            if (string.IsNullOrWhiteSpace(text))
            {
                HttpResponseData? badRequestResponse = req.CreateResponse(HttpStatusCode.BadRequest);

                await badRequestResponse.WriteStringAsync("You should provide a request body to generate a QR code, example: {"text": "https://www.bing.com"}.");

                return badRequestResponse;
            }

            byte[]? qrCodeImage = null;
            var qrImageResponse = req.CreateResponse(HttpStatusCode.OK);
            qrImageResponse.Headers.Add("Content-Type", "image/png");
            
            // Check if the blob exists in the storage and store the content in a byte array
            if (await inputQRCode.ExistsAsync())
            {
                using (var ms = new MemoryStream())
                {
                    inputQRCode.DownloadTo(ms);
                    qrCodeImage = ms.ToArray();
                }
            }
            else
            {
                // Using IronBarcode library to generate QR code
                var qrCode = BarcodeWriter.CreateBarcode(text, BarcodeEncoding.QRCode);
                qrCode.SetMargins(10);
                qrCodeImage = qrCode.ToPngBinaryData();
                using (var ms = new MemoryStream(qrCodeImage, false))
                {
                    await outputQRCode.UploadAsync(ms);
                }
            }

            await qrImageResponse.Body.WriteAsync(qrCodeImage!, 0, qrCodeImage!.Length);

            _logger.LogInformation($"Generate QR function generated a QR code for text {text}.");

            return qrImageResponse;
        }

Deploying the app to Azure

Let’s publish the final code to Azure, there are multiple to deploy, I will be using the CLI:

  • Install and use Azure-related VS Code extensions.
  • Deploy from Visual Studio.
  • Deploy using Azure CLI.

Ensure that have the Azure CLI installed, open the command line in the project’s directory, and type te below commands.

# If you are not already logged in using the CLI type
az login
# If you have mutiple subscriptions set the right one
az account set --subscription <subscription ID or name># Deploy the app to Azure using Core Tools
func azure functionapp publish <FunctionAppName>

Source code can be found on this GitHub repository: https://github.com/ahmadhmoud/AzureFunctionsQRCode/