How to generate a QR in SVG format?

Viewed 1169

I'm attempting to generate a QR code in SVG format. Unfortunately the R qrencoder package only generates raster images e.g. PNG, etc. Therefore this is my first attempt to generate it, plot it in the screen, capture the screen and finally write the screen as a SVG. Maybe there is a simpler way to accomplish this?

library(rsvg)
library(raster)
library(qrencoder)
library(svglite)

tmp <- tempfile()
svglite::svglite(tmp, width = 10, height = 7)
#==============================================
old_mar <- par()$mar
par(mar=c(0,0,0,0))
image(qrencoder::qrencode_raster("http://rud.is/b"), asp=1, col=c("white", "black"),
  axes=FALSE, xlab="", ylab="")
par(mar=old_mar)
#==============================================
dev.off()
rsvg::rsvg_svg(tmp, "out.svg") 

The output file would be out.svg containing the QR code. However, executing the last line rsvg_svg leads to the following error:

(process:733): GdkPixbuf-WARNING **: Cannot open pixbuf loader module file '/usr/local/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache': No such file or directory

This likely means that your installation is broken.
Try running the command
  gdk-pixbuf-query-loaders > /usr/local/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache
to make things work again for the time being.

(process:733): GdkPixbuf-WARNING **: Cannot open pixbuf loader module file '/usr/local/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache': No such file or directory

This likely means that your installation is broken.
Try running the command
  gdk-pixbuf-query-loaders > /usr/local/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache
to make things work again for the time being.

(process:733): GdkPixbuf-WARNING **: Cannot open pixbuf loader module file '/usr/local/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache': No such file or directory

This likely means that your installation is broken.
Try running the command
  gdk-pixbuf-query-loaders > /usr/local/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache
to make things work again for the time being.

I see that Pixbuf is properly installed in macports:

/var/root$ port installed | grep pixbuf
gdk-pixbuf2 @2.36.9_0+x11
gdk-pixbuf2 @2.36.11_0+x11 (active)

I have no idea what the real issue is ... is there a simpler way to generate a QR in SVG format? maybe a simpler API preferably not involving having to plot to the screen, capture the screen, save the file and reload it?

Otherwise can anyone suggest a fix for this error?

2 Answers

You can also make the svg (which is just a text file) yourself from the inline png code generated by qrencoder, as in

library(qrencoder)

qrencode_svg <- function(string, filename, width = "2cm", height = "2cm") {
  inline_png <- qrencode_png(string)
  con <- file(filename, open = "w+")
  cat("<?xml version='1.0' encoding='UTF-8' ?>\n", file = con)
  cat("<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' ",
      "width='", width, "' height='", height, "'>\n", file = con, sep = "")
  cat("<image width='", width, "' height='", height, "' x='0' y='0' xlink:href='", inline_png, "'/>\n",
      file = con, sep = "")
  cat("</svg>\n", file = con)
  close(con)
}
qrencode_svg("http://rud.is/b", "test.svg", width = "2cm", height = "2cm")

However, the result gets blurry when the size is too large, so I am just posting here for completeness. Or maybe someone knows how to improve it.

Version 0.2.0 of qrencoder now has preliminary SVG support (thx to this question). It does the SVG build in C:

# devtools::install_github("hrbrmstr/qrencoder")

library(qrencoder)

cat(qrencode_svg("https://rud.is/b"))
#> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
#> <!-- Created with qrencode 3.9.0 (http://fukuchi.org/works/qrencode/index.html.en) -->
#> <svg width="3.07cm" height="3.07cm" viewBox="0 0 29 29" preserveAspectRatio="none" version="1.1" xmlns="http://www.w3.org/2000/svg">
#>  <g id="QRcode">
#>      <rect x="0" y="0" width="29" height="29" fill="#ffffff" />
#>      <g id="Pattern">
#>          <rect x="4" y="4" width="7" height="1" fill="#000000" />
#>          <rect x="13" y="4" width="1" height="1" fill="#000000" />
#>          <rect x="16" y="4" width="1" height="1" fill="#000000" />
#>          <rect x="18" y="4" width="7" height="1" fill="#000000" />
#>          <rect x="4" y="5" width="1" height="1" fill="#000000" />
...

Live example (wrote ^^ to a file):

Let me know what API changes you would like. There are additional parameters (like margin — hence the whitespace below — and others) that I'll likely add to other functions. I've got tons of flexibility in the output and tend to only tweak the pkg when I see GH issues or SO questions.

I'm keen to let the "Created with" comment in there since I'm using (and attribute broadly) the qrencode library and that author does deserve credit for their work. But I can also make it an option to turn it off.

Related