Cómo generar códigos QR en el navegador con JavaScript puro

Generar un QR en el navegador es sorprendentemente accesible gracias a qrcode-generator: una librería de 4,5 KB que expone una API mínima y produce SVG vectorial listo para imprimir.

Generador de códigos QR online: campo de texto con URL y código QR generado al instante

Generar un código QR de cero requiere implementar la codificación Reed-Solomon, las matrices de datos, los patrones de sincronización y ocho máscaras posibles. Nadie debería hacer eso cuando existe qrcode-generator, una librería de 4,5 KB minificada que lleva más de una década siendo la opción de referencia y que no tiene ninguna dependencia.

La librería y su API

qrcode-generator de kazuhikoarase expone una función global qrcode(typeNumber, errorCorrectionLevel). El typeNumber va del 1 al 40 e indica la versión del QR (a más número, más módulos, más datos caben). Pasando 0 la librería selecciona automáticamente la versión mínima que admite el texto introducido:

var qr = qrcode(0, 'M');
qr.addData('https://paigar.eu');
qr.make();

Tras make(), el objeto qr tiene el QR calculado y listo para renderizar.

Salida SVG vectorial

El método más útil para web es createSvgTag(), que devuelve un string con un SVG completo. Con el parámetro scalable: true, el SVG no lleva atributos width ni height —solo un viewBox— y puede redimensionarse con CSS sin perder calidad:

var svg = qr.createSvgTag({
  scalable: true,
  margin: 8
});
document.getElementById('qr-container').innerHTML = svg;

Para descargar como fichero, en cambio, conviene generar una versión con dimensiones explícitas. Un cellSize de 10 da módulos de 10 px, lo que produce un SVG de unos 500–700 px de lado dependiendo de la cantidad de datos:

var svgDescarga = qr.createSvgTag({ cellSize: 10, margin: 40 });
var blob = new Blob([svgDescarga], { type: 'image/svg+xml;charset=utf-8' });
var url  = URL.createObjectURL(blob);
var a    = document.createElement('a');
a.href     = url;
a.download = 'qrcode.svg';
a.click();
URL.revokeObjectURL(url);

Descargar como PNG

Para exportar a PNG hay que pasar por un <canvas>. Se carga el SVG como imagen, se dibuja en el canvas y se exporta con toDataURL:

var img = new Image();
img.onload = function () {
  var canvas = document.createElement('canvas');
  canvas.width = canvas.height = 512;
  var ctx = canvas.getContext('2d');
  ctx.fillStyle = 'white';
  ctx.fillRect(0, 0, 512, 512);
  ctx.drawImage(img, 0, 0, 512, 512);
  URL.revokeObjectURL(url);        // liberar el blob url
  var a = document.createElement('a');
  a.download = 'qrcode.png';
  a.href     = canvas.toDataURL('image/png');
  a.click();
};
img.src = url;  // url del blob SVG creado antes

Corrección de error

El segundo argumento de qrcode() controla cuántos módulos pueden dañarse y aun así escanearse correctamente:

NivelRecuperaciónCuándo usarlo
L7 %URLs largas; impresión de calidad
M15 %Uso general (recomendado)
Q25 %Impresión con posible suciedad
H30 %Para superponer un logo encima

A mayor corrección, más módulos necesita el QR y más denso queda. Con M y una URL corta, el código es cómodo de escanear con cualquier cámara.

Soporte UTF-8

Por defecto la librería codifica en modo Byte a nivel de carácter, lo que no funciona bien con acentos o emoji. Para soportar UTF-8 correctamente hay que reemplazar la función stringToBytes antes de llamar a addData:

qrcode.stringToBytes = function (text) {
  var bytes = [];
  for (var i = 0; i < text.length; i++) {
    var c = text.charCodeAt(i);
    if (c < 0x80) {
      bytes.push(c);
    } else if (c < 0x800) {
      bytes.push(0xC0 | c >> 6, 0x80 | c & 0x3F);
    } else if (c < 0xD800 || c >= 0xE000) {
      bytes.push(0xE0 | c >> 12, 0x80 | c >> 6 & 0x3F, 0x80 | c & 0x3F);
    } else {
      i++;
      c = 0x10000 + ((c & 0x3FF) << 10 | text.charCodeAt(i) & 0x3FF);
      bytes.push(0xF0 | c >> 18, 0x80 | c >> 12 & 0x3F, 0x80 | c >> 6 & 0x3F, 0x80 | c & 0x3F);
    }
  }
  return bytes;
};

Con esto la herramienta soporta cualquier carácter: tildes, ñ, emoji, chino, árabe. El lector QR del destinatario también deberá interpretar la cadena como UTF-8, pero todos los lectores modernos lo hacen.

A continuación puedes probar la herramienta completa.

Abrir en página propia

Herramienta · paigar.eu

Generador de códigos QR

Introduce el texto, URL o dato que quieres codificar. El código QR se genera en tu navegador al instante.

Corrección de error
Escribe algo para generar el QR
Prueba con estos ejemplos
URLpaigar.eu
Emailmailto:
Teléfonotel:
WiFiWi-Fi
TextoTexto libre
···
Otras entradas