Skip to content

Commit

Permalink
Merge pull request #250 from kozakdenys/set-save-as-blob-as-default
Browse files Browse the repository at this point in the history
Fix browser image not rendered, set saveAsBlob=true by default, as it was before 1.6.0 version
  • Loading branch information
kozakdenys authored Oct 21, 2024
2 parents a2a5224 + 4ff4e27 commit 24de6f3
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 38 deletions.
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,13 @@ errorCorrectionLevel|string (`'L' 'M' 'Q' 'H'`) |`'Q'`

`options.imageOptions` structure

Property |Type |Default Value|Description
------------------|---------------------------------------|-------------|------------------------------------------------------------------------------
hideBackgroundDots|boolean |`true` |Hide all dots covered by the image
imageSize |number |`0.4` |Coefficient of the image size. Not recommended to use ove 0.5. Lower is better
margin |number |`0` |Margin of the image in px
crossOrigin |string(`'anonymous' 'use-credentials'`)| |Set "anonymous" if you want to download QR code from other origins.
saveAsBlob |boolean |`false` |Saves image as base64 blob in svg type, see bellow
Property |Type | Default Value |Description
------------------|---------------------------------------|---------------|------------------------------------------------------------------------------
hideBackgroundDots|boolean | `true` |Hide all dots covered by the image
imageSize |number | `0.4` |Coefficient of the image size. Not recommended to use ove 0.5. Lower is better
margin |number | `0` |Margin of the image in px
crossOrigin |string(`'anonymous' 'use-credentials'`)| |Set "anonymous" if you want to download QR code from other origins.
saveAsBlob |boolean | `true` |Saves image as base64 blob in svg type, see bellow

When QR type is svg, the image may not load in certain applications as it is saved as a url, and some svg applications will not render url images for security reasons. Setting `saveAsBlob` to true will instead save the image as a blob, allowing it to render correctly in more places, but will also increase the file size.

Expand Down
3 changes: 3 additions & 0 deletions src/core/QRCodeStyling.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ describe("Test QRCodeStyling class", () => {
},
backgroundOptions: {
color: "#e9ebee"
},
imageOptions: {
saveAsBlob: false
}
});
qrCode.getRawData("svg").then((buffer) => {
Expand Down
2 changes: 1 addition & 1 deletion src/core/QROptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const defaultOptions: RequiredOptions = {
errorCorrectionLevel: errorCorrectionLevels.Q
},
imageOptions: {
saveAsBlob: false,
saveAsBlob: true,
hideBackgroundDots: true,
imageSize: 0.4,
crossOrigin: undefined,
Expand Down
36 changes: 9 additions & 27 deletions src/core/QRSVG.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import calculateImageSize from "../tools/calculateImageSize";
import toDataUrl from "../tools/toDataUrl";
import errorCorrectionPercents from "../constants/errorCorrectionPercents";
import QRDot from "../figures/dot/QRDot";
import QRCornerSquare from "../figures/cornerSquare/QRCornerSquare";
Expand All @@ -7,7 +8,7 @@ import { RequiredOptions } from "./QROptions";
import gradientTypes from "../constants/gradientTypes";
import shapeTypes from "../constants/shapeTypes";
import { QRCode, FilterFunction, Gradient, Window } from "../types";
import { Canvas as NodeCanvas, Image } from "canvas";
import { Image } from "canvas";

const squareMask = [
[1, 1, 1, 1, 1, 1, 1],
Expand All @@ -30,8 +31,6 @@ const dotMask = [
];

export default class QRSVG {
_domCanvas?: HTMLCanvasElement;
_nodeCanvas?: NodeCanvas;
_window: Window;
_element: SVGElement;
_defs: SVGElement;
Expand Down Expand Up @@ -60,18 +59,6 @@ export default class QRSVG {
this._element.setAttribute("viewBox", `0 0 ${options.width} ${options.height}`);
this._defs = this._window.document.createElementNS("http://www.w3.org/2000/svg", "defs");
this._element.appendChild(this._defs);

if (options.imageOptions.saveAsBlob) {
if (options.nodeCanvas?.createCanvas) {
this._nodeCanvas = options.nodeCanvas.createCanvas(options.width, options.height);
this._nodeCanvas.width = options.width;
this._nodeCanvas.height = options.height;
} else {
this._domCanvas = document.createElement("canvas");
this._domCanvas.width = options.width;
this._domCanvas.height = options.height;
}
}
this._imageUri = options.image;
this._instanceId = QRSVG.instanceCount++;
this._options = options;
Expand Down Expand Up @@ -471,15 +458,11 @@ export default class QRSVG {
options.nodeCanvas
.loadImage(options.image)
.then((image: Image) => {
// fix blurry svg
if (/(\.svg$)|(^data:image\/svg)/.test(options.image ?? "")) {
image.width = this._options.width;
image.height = this._options.height;
}
this._image = image;
if (this._options.imageOptions.saveAsBlob && this._nodeCanvas) {
this._nodeCanvas.getContext('2d')?.drawImage(image, 0, 0, this._nodeCanvas.width, this._nodeCanvas.height);
this._imageUri = this._nodeCanvas.toDataURL('image/png');
if (this._options.imageOptions.saveAsBlob) {
const canvas = options.nodeCanvas?.createCanvas( this._image.width, this._image.height);
canvas?.getContext('2d')?.drawImage(image, 0, 0);
this._imageUri = canvas?.toDataURL();
}
resolve();
})
Expand All @@ -492,10 +475,9 @@ export default class QRSVG {
}

this._image = image;
image.onload = (): void => {
if (this._options.imageOptions.saveAsBlob && this._domCanvas) {
this._domCanvas.getContext('2d')?.drawImage(image, 0, 0, this._domCanvas.width, this._domCanvas.height);
this._imageUri = this._domCanvas.toDataURL('image/png');
image.onload = async () => {
if (this._options.imageOptions.saveAsBlob) {
this._imageUri = await toDataUrl(options.image || "", this._window);
}
resolve();
};
Expand Down
8 changes: 5 additions & 3 deletions src/tools/toDataUrl.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
export default async function toDataURL(url: string): Promise<string> {
import { Window } from "../types";

export default async function toDataURL(url: string, window: Window): Promise<string> {
return new Promise((resolve) => {
const xhr = new XMLHttpRequest();
const xhr = new window.XMLHttpRequest();
xhr.onload = function () {
const reader = new FileReader();
const reader = new window.FileReader();
reader.onloadend = function () {
resolve(reader.result as string);
};
Expand Down

0 comments on commit 24de6f3

Please sign in to comment.