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" ); }); }