Skip to content

Commit

Permalink
#94 added clear image option to "cut out" parts of the qr-code and ad…
Browse files Browse the repository at this point in the history
…d an image
  • Loading branch information
werthdavid committed Jun 3, 2024
1 parent c6ad86c commit 0e59e89
Show file tree
Hide file tree
Showing 11 changed files with 60 additions and 10 deletions.
14 changes: 10 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
[![NPM version](https://img.shields.io/npm/v/ngx-kjua.svg?&label=npm)](https://www.npmjs.com/package/ngx-kjua)
[![Dependency Status](https://david-dm.org/werthdavid/ngx-kjua.svg)](https://david-dm.org/werthdavid/ngx-kjua)
[![Downloads](https://img.shields.io/npm/dm/ngx-kjua.svg)](https://npmjs.org/package/ngx-kjua)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](http://makeapullrequest.com)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/2ef6c180329a44cc9fd95abc77fc8c1d)](https://www.codacy.com/app/werthdavid/ngx-kjua?utm_source=github.com&utm_medium=referral&utm_content=werthdavid/ngx-kjua&utm_campaign=Badge_Grade)
<img align="right" src="https://raw.githubusercontent.com/werthdavid/ngx-kjua/master/docs/readme-logo.png"/>

If you find my work useful you can buy me a coffee, I am very thankful for your support.
Expand Down Expand Up @@ -110,6 +108,8 @@ Once the package is imported, you can use it in your Angular application:

## Options

:exclamation: *Caution*: When adding images, label or similar, this will reduce the readability of the QR-code. Consider using a higher error correction level (e.g. L) in those cases.

### Crisp

As you can set the size of the image, the amount of 'modules' (black/white boxes that make up the QR-code) is calculated based on the size and the amount of `quiet` modules. The calculation can result in an odd number so that a module is e.g. 4.5 pixels big. The resulting image will be drawn fuzzy if `crisp` is set to false. Setting it to `true` will result in 'sharp' lines.
Expand All @@ -131,7 +131,13 @@ This can reduce the readability of the code!
### Image as Code
<img src="https://raw.githubusercontent.com/werthdavid/kjua/master/docs/image-as-code.png"/>

### Labelimage and Imagelabel
### Clear + Image
<img src="https://raw.githubusercontent.com/werthdavid/ngx-kjua/master/docs/clearimage.png"/>

This mode let's you "cut out" parts of the QR-code and at the same time add an image.


### labelimage, imagelabel and clearimage
Use this, if you want a label AND an image. In these modes `mSize`, `mPosX` and `mPosY` can be provided as an array.
In mode `labelimage`, the first value (index 0) of the `mSize`, `mPosX` and `mPosY` arrays is used for the label,
the second value (index 1) is used for image and vice versa. Also in `labelimage` mode, the label is drawn before the
Expand All @@ -149,7 +155,7 @@ image is drawn and therefore kinda "in the background" if the two overlap.
* `back` background color (defaults to `#fff`, for transparent use `''` or `null`)
* `rounded` roundend corners in pc: 0..100 (defaults to `0`, not working if `render`is set to `svg`)
* `quiet` quiet zone in modules (defaults to `0`)
* `mode` modes: 'plain', 'label' or 'image' (defaults to `plain`, set `label` or `image` property if you change this)
* `mode` modes: 'plain', 'label', 'image' or 'clear' (defaults to `plain`, set `label` or `image` property if you change this)
* `mSize` label/image size in pc: 0..100 (defaults to `30`)
* `mPosX` label/image pos x in pc: 0..100 (defaults to `50`)
* `mPosY` label/image pos y in pc: 0..100 (defaults to `50`)
Expand Down
Binary file added docs/clearimage.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "ngx-kjua-library",
"description": "ngx-kjua library builder",
"version": "18.0.0",
"version": "18.1.0",
"license": "MIT",
"scripts": {
"ng": "ng",
Expand Down
2 changes: 1 addition & 1 deletion projects/ngx-kjua/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "ngx-kjua",
"description": "Angular QR-Code generator component.",
"version": "18.0.0",
"version": "18.1.0",
"license": "MIT",
"private": false,
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion projects/ngx-kjua/src/lib/kjua/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export interface KjuaOptions {
/**
* modes: 'plain', 'label', 'image', 'imagelabel' or 'labelimage'
*/
mode?: "plain" | "label" | "image" | "imagelabel" | "labelimage";
mode?: "plain" | "label" | "image" | "imagelabel" | "labelimage" | "clearimage";

/**
* label/image size and pos in pc: 0..100
Expand Down
17 changes: 16 additions & 1 deletion projects/ngx-kjua/src/lib/kjua/lib/create_canvas_qrcode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@ export const draw_modules = (qr: any, ctx: any, settings: any) => {
const draw = (qr: any, ctx: any, settings: any) => {
draw_background(ctx, settings);
draw_modules(qr, ctx, settings);
draw_mode(ctx, settings);
if (settings.mode !== "clearimage") {
// we do this later manually
draw_mode(ctx, settings);
}
};

export const create_canvas_qrcode = (qr: any, settings: any, as_image: any) => {
Expand All @@ -81,5 +84,17 @@ export const create_canvas_qrcode = (qr: any, settings: any, as_image: any) => {

context.scale(ratio, ratio);
draw(qr, context, settings);
if (settings.mode === "clearimage") {
// draw_modules(qr, ctx2, settings);
const imagePos = dom.calc_image_pos(settings);
context.globalCompositeOperation = "destination-out";
context.fillStyle = "deeppink"; // any color works
context.fillRect(imagePos.x,
imagePos.y,
imagePos.iw,
imagePos.ih);
context.globalCompositeOperation = "source-over";
draw_mode(context, settings);
}
return as_image ? dom.canvas_to_img(canvas, settings.elementId) : canvas;
};
20 changes: 20 additions & 0 deletions projects/ngx-kjua/src/lib/kjua/lib/create_svg_qrcode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,19 @@ export const create_svg_qrcode = (qr: any, settings: any) => {
image: get_attr(settings.image, "src"),
});
}

if (settings.mode === "clearimage") {
const ratio = settings.ratio || dpr;
const canvas = create_canvas(settings.size, ratio);
const ctx2 = canvas.getContext("2d");
const imagePos = calc_image_pos(settings);
ctx2.globalCompositeOperation = "destination-in";
ctx2.fillStyle = "deeppink";
ctx2.fillRect(imagePos.x,
imagePos.y,
imagePos.iw,
imagePos.ih)
}
}
if (mode === "label") {
add_label(svg_el, settings);
Expand All @@ -341,6 +354,13 @@ export const create_svg_qrcode = (qr: any, settings: any) => {
} else if (mode === "imagelabel") {
add_image(svg_el, settings);
add_label(svg_el, settings);
} else if (mode === "clearimage") {
// We set the mode to "labelimage" here. this will change to behavior of calc_image_pos() to use
// the arrayposition 1 (that means, the second position in the pos-array is used for drawing the image.
// the first position in the pos-array is used for clearing the background via "destination-out").
// We can't just change the calc_image_pos() to use arrayposition 1 in the case of clearimage as we
// call this function as well to calculate the area to be cleared
add_image(svg_el, {...settings, mode: "labelimage"});
}

return svg_el;
Expand Down
7 changes: 7 additions & 0 deletions projects/ngx-kjua/src/lib/kjua/lib/draw_mode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,5 +65,12 @@ export const draw_mode = (ctx: any, settings: any) => {
} else if (mode === "imagelabel") {
draw_image(ctx, settings);
draw_label(ctx, settings);
} else if (mode === "clearimage") {
// We set the mode to "labelimage" here. this will change to behavior of calc_image_pos() to use
// the arrayposition 1 (that means, the second position in the pos-array is used for drawing the image.
// the first position in the pos-array is used for clearing the background via "destination-out").
// We can't just change the calc_image_pos() to use arrayposition 1 in the case of clearimage as we
// call this function as well to calculate the area to be cleared
draw_image(ctx, {...settings, mode: "labelimage"});
}
};
1 change: 1 addition & 0 deletions projects/ngx-kjua/src/lib/ngx-kjua.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export type KjuaMode =
| "label"
| "image"
| "imagelabel"
| "clearimage"
| "labelimage";
3 changes: 2 additions & 1 deletion src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,14 @@
<option value="image">image</option>
<option value="imagelabel">imagelabel</option>
<option value="labelimage">labelimage</option>
<option value="clearimage">clearimage</option>
</select>
<hr>
<label for="msize">SIZE: {{mSize}}%</label><input id="msize" type="range" value="30" min="0" max="100" step="1" [(ngModel)]="mSize">
<label for="mposx">POS X: {{mPosX}}%</label><input id="mposx" type="range" value="50" min="0" max="100" step="1" [(ngModel)]="mPosX">
<label for="mposy">POS Y: {{mPosY}}%</label><input id="mposy" type="range" value="50" min="0" max="100" step="1" [(ngModel)]="mPosY">
<hr>
<div *ngIf="mode === 'labelimage' || mode === 'imagelabel'">
<div *ngIf="mode === 'labelimage' || mode === 'imagelabel' || mode === 'clearimage'">
<label for="msize2">SIZE2: {{mSize2}}%</label><input id="msize2" type="range" value="30" min="0" max="100" step="1" [(ngModel)]="mSize2">
<label for="mposx2">POS X2: {{mPosX2}}%</label><input id="mposx2" type="range" value="50" min="0" max="100" step="1" [(ngModel)]="mPosX2">
<label for="mposy2">POS Y2: {{mPosY2}}%</label><input id="mposy2" type="range" value="50" min="0" max="100" step="1" [(ngModel)]="mPosY2">
Expand Down
2 changes: 1 addition & 1 deletion src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export class AppComponent implements AfterViewInit {
size = 400;
ratio = undefined;
fill = "#333333";
back = "#ffffff";
back = "transparent";
rounded = 0;
quiet = 1;
mode: KjuaMode = "label";
Expand Down

0 comments on commit 0e59e89

Please sign in to comment.