Skip to content

Commit eecabc9

Browse files
melangerxkureck
authored andcommitted
feat(user-profile): downsize antiphishing images
shrink image down to 100x100 and try even smaller sizes up to 50x50 until the desired size is reached
1 parent e52a73f commit eecabc9

File tree

1 file changed

+41
-9
lines changed

1 file changed

+41
-9
lines changed

apps/user-profile/src/app/components/dialogs/add-auth-img-dialog/add-auth-img-dialog.component.ts

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ export interface AddAuthImgDialogData {
88
attribute: Attribute;
99
}
1010

11+
const MAX_SIZE = 100;
12+
const MIN_SIZE = 50;
13+
const MAX_LENGTH = 5120;
14+
1115
@Component({
1216
selector: 'perun-web-apps-add-auth-img-dialog',
1317
templateUrl: './add-auth-img-dialog.component.html',
@@ -31,6 +35,7 @@ export class AddAuthImgDialogComponent implements OnInit {
3135
this.theme = this.data.theme;
3236
this.attribute = this.data.attribute;
3337
this.newImage = this.attribute.value as unknown as string;
38+
this.imageType = null;
3439
}
3540

3641
handleInputChange(e: Event | DragEvent): void {
@@ -42,13 +47,41 @@ export class AddAuthImgDialogComponent implements OnInit {
4247
return;
4348
}
4449
reader.onload = this._handleReaderLoaded.bind(this) as () => void;
50+
this.imageType = file.type;
4551
reader.readAsDataURL(file);
4652
}
4753

48-
_handleReaderLoaded(e: ProgressEvent): void {
49-
const reader = e.target as FileReader;
50-
const result = reader.result as string;
51-
this.imgTooLong = result.length >= 5120;
54+
_handleReaderLoaded(e) {
55+
const reader = e.target;
56+
57+
let size = MAX_SIZE;
58+
let result = null;
59+
do {
60+
const img = document.createElement("img");
61+
img.src = reader.result;
62+
const canvas = document.createElement("canvas");
63+
let ctx = canvas.getContext("2d");
64+
ctx.drawImage(img, 0, 0);
65+
const width = img.width;
66+
const height = img.height;
67+
if (width > height) {
68+
if (width > MAX_SIZE) {
69+
height *= MAX_SIZE / width;
70+
width = MAX_SIZE;
71+
}
72+
} else if (height > MAX_SIZE) {
73+
width *= MAX_SIZE / height;
74+
height = MAX_SIZE;
75+
}
76+
canvas.width = width;
77+
canvas.height = height;
78+
ctx = canvas.getContext("2d");
79+
ctx.drawImage(img, 0, 0, width, height);
80+
result = canvas.toDataURL(this.imageType);
81+
size -= 10;
82+
} while(size >= MIN_SIZE && result.length >= MAX_LENGTH);
83+
84+
this.imgTooLong = result.length >= MAX_LENGTH;
5285
this.newImage = result;
5386
}
5487

@@ -73,20 +106,19 @@ export class AddAuthImgDialogComponent implements OnInit {
73106
const MIN_COLOR = 120; // Min value for a color component
74107
const FILL_CHANCE = 0.5; // Chance of a square being filled [0, 1]
75108
const SQUARE = 20; // Size of a grid square in pixels
76-
const GRID = 5; // Number of squares width and height
77-
const SIZE = SQUARE * GRID; // Size of the canvas
109+
const GRID = MAX_SIZE / SQUARE; // Number of squares width and height
78110
const FILL_COLOR = '#FFFFFF'; // canvas background color
79111

80112
/* Create a temporary canvas */
81113
function setupCanvas(): HTMLCanvasElement {
82114
const canvas = document.createElement('canvas');
83-
canvas.width = SIZE;
84-
canvas.height = SIZE;
115+
canvas.width = MAX_SIZE;
116+
canvas.height = MAX_SIZE;
85117

86118
// Fill canvas background
87119
const context = canvas.getContext('2d');
88120
context.beginPath();
89-
context.rect(0, 0, SIZE, SIZE);
121+
context.rect(0, 0, MAX_SIZE, MAX_SIZE);
90122
context.fillStyle = FILL_COLOR;
91123
context.fill();
92124
return canvas;

0 commit comments

Comments
 (0)