Suggestion: Improve QRCode ToPng() API and Add Output Size/Scale Options

Hi Radzen team,

First of all, thank you for providing the QRCode component. It works well and is very easy to use.

I have a small API suggestion that I believe would make it much more flexible.

Current behavior

Currently there are two export methods:

  • ToSvg() returns the SVG content as a string.

  • ToPng() converts the SVG to PNG and immediately downloads the image.

This makes ToPng() difficult to use in scenarios where developers need the PNG data instead of downloading it directly, such as:

  • Saving to a database

  • Returning the image from an API

  • Embedding it into a PDF or Word document

  • Processing it further before sending it to the client

  • Uploading it to cloud storage

Suggested changes

Instead of the current behavior, I would suggest separating the two responsibilities:

  • Keep the current download functionality, but rename it to something like:

    • DownloadPng()
  • Change ToPng() so that it returns the generated PNG instead of downloading it automatically, for example:

    • byte[]

    • Stream

    • or another suitable image representation.

This would make the API more consistent with ToSvg(), which already returns the generated content instead of triggering a download.

Output size / scale

It would also be very useful if both DownloadPng() and ToPng() accepted optional parameters to control the output size, for example:

  • width

  • height

  • scale

This would allow developers to generate higher-resolution QR codes without having to post-process the image themselves.

Example:

var png = qrCode.ToPng(width: 1000, height: 1000);
// or
var png = qrCode.ToPng(scale: 4);

Benefits

  • Better separation of responsibilities.

  • More consistent API design.

  • Supports many server-side and document-generation scenarios.

  • Gives developers control over the output resolution.

  • Existing download functionality can still be preserved through DownloadPng().

I think these changes would make the QRCode API much more flexible while remaining fully backward compatible if DownloadPng() is introduced alongside the new ToPng() behavior.

Thank you for considering this suggestion!

Thanks for the suggestion! We accept pull requests!

Thanks for the response!

I'd be happy to contribute, but at the moment I only have an implementation that uses SkiaSharp to convert SVG to PNG. I'm not sure whether adding a dependency on SkiaSharp would be acceptable for Radzen, or if you'd prefer a solution without introducing any additional dependencies.

If SkiaSharp isn't suitable, I'd appreciate any guidance on the preferred approach for implementing this feature within the project.

 public static byte[] ConvertSvgToPng(string svgContent, int outputSize)
 {
     using var skSvg = new SKSvg();
     skSvg.FromSvg(svgContent);

     if (skSvg.Picture is null)
         return [];

     var bounds = skSvg.Picture.CullRect;

     using var surface = SKSurface.Create(
         new SKImageInfo(
             outputSize,
             outputSize,
             SKColorType.Rgba8888,
             SKAlphaType.Premul));

     if (surface is null)
         return [];

     var canvas = surface.Canvas;
     canvas.Clear(SKColors.Transparent);

     float scale = Math.Min(
         outputSize / bounds.Width,
         outputSize / bounds.Height);

     float scaledWidth = bounds.Width * scale;
     float scaledHeight = bounds.Height * scale;

     float offsetX = (outputSize - scaledWidth) / 2f;
     float offsetY = (outputSize - scaledHeight) / 2f;

     canvas.Translate(offsetX, offsetY);
     canvas.Scale(scale);
     canvas.Translate(-bounds.Left, -bounds.Top);

     using var paint = new SKPaint
     {
         IsAntialias = true
     };

     canvas.DrawPicture(skSvg.Picture, paint);
     canvas.Flush();

     using var image = surface.Snapshot();
     using var data = image.Encode(SKEncodedImageFormat.Png, 100);

     return data?.ToArray() ?? [];
 }

No, third party are not acceptable. I’ll push overload with requested functionallty.

1 Like

Thanks! That sounds great.

I completely understand the decision to avoid third-party dependencies. Adding overloads with the requested functionality would cover my use case perfectly.

Thank you for considering the suggestion and for your quick response!