neocotic / qrious

Pure JavaScript library for QR code generation using canvas
https://neocotic.com/qrious
Other
1.53k stars 214 forks source link

Add logo support #100

Open yanickrochon opened 7 years ago

yanickrochon commented 7 years ago

It would be nice to be able to add some logo to the QR code. If the code becomes unreadable falls to the scope of another project :smile:

yanickrochon commented 7 years ago

I just implemented this function, and the QR Code is decoded just fine :

function drawLogo() {
  var ctx = canvas.getContext("2d");
  var logoWidth = logo.width;
  var logoHeight = logo.height;
  var width = qr.size / 3;
  var height = logoHeight / logoWidth * width;
  var x = (qr.size / 2) - (width / 2);
  var y = (qr.size / 2) - (height / 2);
  var maskPadding = qr.size / 30;

  ctx.globalCompositeOperation = 'destination-out';
  ctx.drawImage(logo, 0, 0, logoWidth, logoHeight, x - maskPadding, y - maskPadding, width + (maskPadding * 2), height + (maskPadding * 2));

  ctx.globalCompositeOperation = 'source-over';
  ctx.drawImage(logo, 0, 0, logoWidth, logoHeight, x, y, width, height);
}

Of course, this works for my case, but other options could be provided (i.e. maskPadding)

kahu08 commented 6 years ago

is there a way one can add an image to the qr being printed?

zendre4 commented 6 years ago

+1

fssgh commented 5 years ago
  async function drawLogo() {
        let imgLogoEl = document.createElement("img");
        imgLogoEl.src = this._htOption.logo;
        /**
         * 矩形
         * @param x 
         * @param y 
         * @param w 
         * @param h 
         */
        let Rect = (x, y, w, h) => {
            return { x: x, y: y, width: w, height: h };
        }
        /**
         * 点
         * @param x 
         * @param y 
         */
        let Point = function (x, y) {
            return { x: x, y: y };
        };
        /**
         * 绘制圆角矩形
         * @param rect 
         * @param r 圆角弧半径
         * @param ctx 
         */
        let drawRoundedRect = (rect, r, ctx) => {
            var ptA = Point(rect.x + r, rect.y);
            var ptB = Point(rect.x + rect.width, rect.y);
            var ptC = Point(rect.x + rect.width, rect.y + rect.height);
            var ptD = Point(rect.x, rect.y + rect.height);
            var ptE = Point(rect.x, rect.y);

            ctx.beginPath();
            ctx.strokeStyle = "#000000";
            ctx.lineWidth = 1;
            ctx.moveTo(ptA.x, ptA.y);
            ctx.arcTo(ptB.x, ptB.y, ptC.x, ptC.y, r);
            ctx.arcTo(ptC.x, ptC.y, ptD.x, ptD.y, r);
            ctx.arcTo(ptD.x, ptD.y, ptE.x, ptE.y, r);
            ctx.arcTo(ptE.x, ptE.y, ptA.x, ptA.y, r);
            ctx.fillStyle = '#ffffff';
            ctx.fill();
            ctx.stroke();
        }
        return new Promise((resolve, reject) => {
            imgLogoEl.onerror = () => {
                reject('qrlogo load error')
            };
            imgLogoEl.onload = () => {
                let logoWidth = imgLogoEl.width;
                let logoHeight = imgLogoEl.height;
                let width = this._htOption.size / 4;
                let height = logoHeight / logoWidth * width;
                let x = (this._htOption.size / 2) - (width / 2);
                let y = (this._htOption.size / 2) - (height / 2);
                let maskPadding = this._htOption.size / 30;
                let rect = Rect(x - maskPadding, y - maskPadding, width + (maskPadding * 2), height + (maskPadding * 2));
                //绘制圆角矩形 logo 背景
                drawRoundedRect(rect, 10, this._oContext);
                this._oContext.drawImage(imgLogoEl, 0, 0, logoWidth, logoHeight, x, y, width, height);
                imgLogoEl.remove();
                resolve(true)
            }
        });
    }
SlideMovies commented 2 years ago

Still no update after 5 years?

yanickrochon commented 2 years ago

Since the project hasn't been updated in 5 years, it seems like maybe @neocotic abandoned it?

ROBERT-MCDOWELL commented 2 years ago

the guys must create a PR to be validated.

SwapnilSoni1999 commented 1 year ago

I think no