forked from trustwallet/assets
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathimage.ts
More file actions
123 lines (108 loc) · 4.54 KB
/
image.ts
File metadata and controls
123 lines (108 loc) · 4.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import * as sharp from "sharp";
import * as tinify from "tinify";
import * as image_size from "image-size";
import {
writeFileSync,
getFileSizeInKilobyte
} from "./filesystem";
import * as chalk from 'chalk';
import * as config from "../config";
export const minLogoWidth = config.imageMinLogoWidth;
export const minLogoHeight = config.imageMinLogoHeight;
export const maxLogoWidth = config.imageMaxLogoWidth;
export const maxLogoHeight = config.imageMaxLogoHeight;
export const maxLogoSizeInKilobyte = config.imageMaxLogoSizeKb;
export function isDimensionTooLarge(width: number, height: number): boolean {
return (width > maxLogoWidth) || (height > maxLogoHeight);
}
export function isDimensionOK(width: number, height: number): boolean {
return (width <= maxLogoWidth) && (height <= maxLogoHeight) &&
(width >= minLogoWidth) && (height >= minLogoHeight);
}
export function calculateTargetSize(srcWidth: number, srcHeight: number, targetWidth: number, targetHeight: number): {width: number, height: number} {
if (srcWidth == 0 || srcHeight == 0) {
return {width: targetWidth, height: targetHeight};
}
const ratio = Math.min(targetWidth / srcWidth, targetHeight / srcHeight);
return {
width: Math.round(srcWidth * ratio),
height: Math.round(srcHeight * ratio)
};
}
// check logo dimensions (pixel) and size (kilobytes)
export async function isLogoOK(path: string): Promise<[boolean, string]> {
let [isOK, msg] = await isLogoDimensionOK(path);
if (!isOK) {
return [false, msg];
}
[isOK, msg] = await isLogoSizeOK(path);
if (!isOK) {
return [false, msg];
}
return [true, ""];
}
const getImageDimensions = (path: string) => image_size.imageSize(path);
async function isLogoDimensionOK(path: string): Promise<[boolean, string]> {
const { width, height } = getImageDimensions(path)
if (isDimensionOK(width, height)) {
return [true, ""];
}
return [false, `Image at path ${path} must have dimensions: min: ${minLogoWidth}x${minLogoHeight} and max: ${maxLogoWidth}x${maxLogoHeight} instead ${width}x${height}`];
}
async function compressTinyPNG(path: string) {
console.log(`Compressing image via tinypng at path ${path}`);
const source = await tinify.fromFile(path);
await source.toFile(path);
}
async function isLogoSizeOK(path: string): Promise<[boolean, string]> {
const sizeKilobyte = getFileSizeInKilobyte(path);
if (sizeKilobyte > maxLogoSizeInKilobyte) {
return [false, `Logo ${path} is too large, ${sizeKilobyte} kB instead of ${maxLogoSizeInKilobyte}`];
}
return [true, ''];
}
// return if image if too large, and if image has been updated
export async function checkResizeIfTooLarge(path: string, checkOnly: boolean): Promise<[boolean, boolean]> {
let tooLarge = false;
let updated = false;
const { width: srcWidth, height: srcHeight } = getImageDimensions(path);
if (!isDimensionOK(srcWidth, srcHeight)) {
tooLarge = true; // may be too small as well
console.log(`Wrong image dimensions, ${srcWidth}x${srcHeight}, ${path}`);
}
if (isDimensionTooLarge(srcWidth, srcHeight)) {
tooLarge = true;
console.log(`Image too large, ${srcWidth}x${srcHeight}, ${path}`);
if (!checkOnly) {
// resize
const { width, height } = calculateTargetSize(srcWidth, srcHeight, maxLogoWidth, maxLogoHeight);
console.log(`Resizing image at ${path} from ${srcWidth}x${srcHeight} => ${width}x${height}`)
await sharp(path).resize(width, height).toBuffer()
.then(data => {
writeFileSync(path, data);
updated = true;
})
.catch(e => {
console.log(chalk.red(e.message));
});
}
}
// If file size > max limit, compress with tinypng
const sizeKilobyte = getFileSizeInKilobyte(path);
if (sizeKilobyte > maxLogoSizeInKilobyte) {
tooLarge = true;
console.log(`Image too big, ${sizeKilobyte} kb, ${path}`);
if (!checkOnly) {
console.log(`Resizing image at path ${path} from ${sizeKilobyte} kB`);
await compressTinyPNG(path)
.then(() => {
updated = true;
console.log(`Resized image at path ${path} from ${sizeKilobyte} kB => ${getFileSizeInKilobyte(path)} kB`);
})
.catch(e => {
console.log(chalk.red(e.message));
});
}
}
return [tooLarge, updated];
}