class Resizer { static resizeAndRotateImage( image: CanvasImageSource, size: number, compressFormat = "jpeg", quality = 100, rotation = 0, ) { var qualityDecimal = quality / 100; var canvas = document.createElement("canvas"); canvas.width = size; canvas.height = size; var ctx = canvas.getContext("2d"); if (ctx) { ctx.fillStyle = "rgba(0, 0, 0, 0)"; ctx.fillRect(0, 0, size, size); if (ctx.imageSmoothingEnabled && ctx.imageSmoothingQuality) { ctx.imageSmoothingQuality = "high"; } if (rotation) { ctx.rotate((rotation * Math.PI) / 180); if (rotation === 90) { ctx.translate(0, -canvas.width); } else if (rotation === 180) { ctx.translate(-canvas.width, -canvas.height); } else if (rotation === 270) { ctx.translate(-canvas.height, 0); } else if (rotation === 0 || rotation === 360) { ctx.translate(0, 0); } } //Вставка картинки. Определяем k в который уменьшилась большая сторона и уменьшаем в него другую сторону let width = Number(image.width); let height = Number(image.height); let Xoffset = 0; let Yoffset = 0; const larger = Math.max(width, height); const k = Number((larger / size).toFixed(2)); if (height > width) { height = size; width = Math.round(width / k); Xoffset = Math.round((size - width) / 2); } else { height = Math.round(width / k); width = size; Yoffset = Math.round((size - height) / 2); } ctx.drawImage(image, Xoffset, Yoffset, width, height); return canvas.toDataURL(`image/${compressFormat}`, qualityDecimal); } else { throw new Error(); } } static b64toByteArrays(b64Data: any, contentType: string) { contentType = contentType || "image/jpeg"; var sliceSize = 512; var byteCharacters = atob( b64Data .toString() .replace(/^data:image\/(png|jpeg|jpg|webp);base64,/, ""), ); var byteArrays = []; for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) { var slice = byteCharacters.slice(offset, offset + sliceSize); var byteNumbers = new Array(slice.length); for (var i = 0; i < slice.length; i++) { byteNumbers[i] = slice.charCodeAt(i); } var byteArray = new Uint8Array(byteNumbers); byteArrays.push(byteArray); } return byteArrays; } static b64toBlob(b64Data: any, contentType: string) { const byteArrays = this.b64toByteArrays(b64Data, contentType); var blob = new Blob(byteArrays, { type: contentType }); return blob; } static b64toFile(b64Data: string, fileName: string, contentType: string) { const byteArrays = this.b64toByteArrays(b64Data, contentType); const file = new File(byteArrays, fileName, { type: contentType }); return file; } static createResizedImage( file: File, size: number, compressFormat: string, quality: number, rotation: number, responseUriFunc: any, outputType = "base64", ) { const reader = new FileReader(); if (file) { if (file.type && !file.type.includes("image")) { throw Error("File Is NOT Image!"); } else { reader.readAsDataURL(file); reader.onload = () => { var image = new Image(); //@ts-ignore image.src = reader.result; image.onload = function () { var resizedDataUrl = Resizer.resizeAndRotateImage( image, size, compressFormat, quality, rotation, ); const contentType = `image/${compressFormat}`; switch (outputType) { case "blob": const blob = Resizer.b64toBlob(resizedDataUrl, contentType); responseUriFunc(blob); break; case "base64": responseUriFunc(resizedDataUrl); break; case "file": let fileName = file.name; let fileNameWithoutFormat = fileName .toString() .replace(/(png|jpeg|jpg|webp)$/i, ""); let newFileName = fileNameWithoutFormat.concat( compressFormat.toString(), ); const newFile = Resizer.b64toFile( resizedDataUrl, newFileName, contentType, ); responseUriFunc(newFile); break; default: responseUriFunc(resizedDataUrl); } }; }; reader.onerror = (error: any) => { throw Error(error); }; } } else { throw Error("File Not Found!"); } } } export default { imageFileResizer: ( file: File, size: number, compressFormat: string, quality: number, rotation: number, responseUriFunc: any, outputType: string, ) => { return Resizer.createResizedImage( file, size, compressFormat, quality, rotation, responseUriFunc, outputType, ); }, }; export function resizeFavIcon(blob: Blob) { return new Promise((resolve) => { Resizer.createResizedImage( new File([blob], "image"), 48, "PNG", 100, 0, async (file: Blob) => { resolve(file); }, "blob", ); }); }