{"version":3,"file":"ngx-image-compress.mjs","sources":["../../../projects/ngx-image-compress/src/lib/models/DOC_ORIENTATION.ts","../../../projects/ngx-image-compress/src/lib/image-compress.ts","../../../projects/ngx-image-compress/src/lib/ngx-image-compress.service.ts","../../../projects/ngx-image-compress/src/public-api.ts","../../../projects/ngx-image-compress/src/ngx-image-compress.ts"],"sourcesContent":["/**\n * EXIF tag standard reference\n *\n * Tag Name: Orientation\n * Tag ID: 0x0112\n * Writable: int16u\n * Group: IFD0\n * Values:\n 1 = Horizontal (normal)\n 2 = Mirror horizontal\n 3 = Rotate 180\n 4 = Mirror vertical\n 5 = Mirror horizontal and rotate 270 CW\n 6 = Rotate 90 CW\n 7 = Mirror horizontal and rotate 90 CW\n 8 = Rotate 270 CW\n */\nexport enum DOC_ORIENTATION {\n  Up = 1,                     //Horizontal (normal)\n  Down = 3,                   //Rotate 180\n  Right = 6,                  //Rotate 90 CW\n  Left = 8,                   //Rotate 270 CW\n  UpMirrored = 2,             //Mirror horizontal\n  DownMirrored = 4,           //Mirror vertical\n  LeftMirrored = 5,           //Mirror horizontal and rotate 270 CW\n  RightMirrored = 7,          //Mirror horizontal and rotate 90 CW\n  Default = 0,\n  NotJpeg = -1,\n  NotDefined = -2\n}\n\n","import {Renderer2} from '@angular/core';\nimport {DataUrl} from './models/data-url';\nimport {DOC_ORIENTATION} from './models/DOC_ORIENTATION';\nimport {UploadResponse} from './models/upload-response';\n\nexport class ImageCompress {\n    static getOrientation = (file: File): Promise<DOC_ORIENTATION> =>\n        new Promise<DOC_ORIENTATION>((resolve, reject) => {\n            try {\n                const reader = new FileReader();\n                reader.onload = () => {\n                    const view = new DataView(reader.result as ArrayBuffer);\n                    if (!view.byteLength) {\n                        return resolve(DOC_ORIENTATION.NotDefined);\n                    }\n                    if (view.getUint16(0, false) !== 0xffd8) {\n                        return resolve(DOC_ORIENTATION.NotDefined);\n                    }\n                    const length = view.byteLength;\n                    let offset = 2;\n                    while (offset < length) {\n                        const marker = view.getUint16(offset, false);\n                        offset += 2;\n                        if (marker === 0xffe1) {\n                            if (view.getUint32((offset += 2), false) !== 0x45786966) {\n                                return resolve(DOC_ORIENTATION.NotJpeg);\n                            }\n                            const little = view.getUint16((offset += 6), false) === 0x4949;\n                            offset += view.getUint32(offset + 4, little);\n                            const tags = view.getUint16(offset, little);\n                            offset += 2;\n                            for (let i = 0; i < tags; i++) {\n                                if (view.getUint16(offset + i * 12, little) === 0x0112) {\n                                    return resolve(view.getUint16(offset + i * 12 + 8, little));\n                                }\n                            }\n                        } else if ((marker & 0xff00) !== 0xff00) {\n                            break;\n                        } else {\n                            offset += view.getUint16(offset, false);\n                        }\n                    }\n                    return resolve(DOC_ORIENTATION.NotJpeg);\n                };\n                reader.readAsArrayBuffer(file);\n            } catch (e) {\n                return reject(DOC_ORIENTATION.Default);\n            }\n        });\n\n    static uploadFile = (render: Renderer2, multiple: boolean = true, rejectOnCancel = false): Promise<UploadResponse | UploadResponse[]> =>\n        new Promise(function (resolve, reject) {\n            const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\n\n            Promise.resolve(isSafari)\n                .then(onlyNative => {\n                    if (onlyNative) {\n                        return ImageCompress.generateUploadInputNative(window.document, multiple, rejectOnCancel);\n                    } else {\n                        return ImageCompress.generateUploadInputRenderer(render, multiple, rejectOnCancel);\n                    }\n                })\n                .then((filesList: FileList | null) => {\n                    const files = filesList ? Array.from(filesList) : [];\n                    const orientationPromises = files.map(file => ImageCompress.getOrientation(file));\n                    const readerPromises = files.map(file => ImageCompress.fileToDataURL(file));\n\n                    let orientationsResult: DOC_ORIENTATION[] = [];\n\n                    Promise.all(orientationPromises)\n                        .then((orientations: DOC_ORIENTATION[]) => {\n                            orientationsResult = orientations;\n                            return Promise.all(readerPromises);\n                        })\n                        .then(readerResult => {\n                            const resultArray = readerResult.map((parsedFile, index) => ({\n                                image: parsedFile.dataUrl,\n                                orientation: orientationsResult[index],\n                                fileName: parsedFile.fileName,\n                            }));\n\n                            if (multiple) {\n                                resolve(resultArray);\n                            } else {\n                                resolve(resultArray[0]);\n                            }\n                        });\n                })\n                .catch(err => reject(err));\n        });\n\n    static fileToDataURL = (file: File): Promise<{dataUrl: string; fileName: string}> => {\n        return new Promise<{dataUrl: string; fileName: string}>((resolve, reject) => {\n            const reader = new FileReader();\n            reader.onload = (e: any) => {\n                //myReader.onloadend = (progressEvent: ProgressEvent<FileReader>)\n                resolve({dataUrl: e.target.result, fileName: file.name});\n            };\n            try {\n                reader.readAsDataURL(file);\n            } catch (e) {\n                reject(`ngx-image-compress - probably no file have been selected: ${e}`);\n            }\n        });\n    };\n\n    static generateUploadInputRenderer = (render: Renderer2, multiple: boolean = true, rejectOnCancel = false) => {\n        let lock = false;\n        return new Promise<FileList | null>((resolve, reject) => {\n            const inputElement = render.createElement('input');\n            render.setStyle(inputElement, 'display', 'none');\n            render.setProperty(inputElement, 'type', 'file');\n            render.setProperty(inputElement, 'accept', 'image/*');\n\n            if (multiple) {\n                render.setProperty(inputElement, 'multiple', 'true');\n            }\n\n            render.listen(inputElement, 'click', ($event: MouseEvent) => {\n                ($event.target as any as HTMLInputElement).value = '';\n            });\n\n            render.listen(inputElement, 'change', $event => {\n                lock = true;\n                const files: FileList = $event.target.files;\n                resolve(files);\n            });\n\n            if (rejectOnCancel) {\n                window.addEventListener(\n                    'focus',\n                    () => {\n                        setTimeout(() => {\n                            if (!lock) {\n                                reject(new Error('file upload on blur - no file selected'));\n                            }\n                        }, 300);\n                    },\n                    {once: true}\n                );\n            }\n\n            inputElement.click();\n        });\n    };\n\n    static generateUploadInputNative = (documentNativeApi: any, multiple: boolean = true, rejectOnCancel = false) => {\n        let lock = false;\n        return new Promise<FileList | null>((resolve, reject) => {\n            const inputElement = documentNativeApi.createElement('input');\n            inputElement.id = 'upload-input' + new Date();\n            inputElement.style.display = 'none';\n            inputElement.setAttribute('type', 'file');\n\n            if (multiple) {\n                inputElement.setAttribute('multiple', 'true');\n            }\n\n            documentNativeApi.body.appendChild(inputElement);\n\n            inputElement.addEventListener(\n                'change',\n                () => {\n                    lock = true;\n                    resolve(inputElement.files);\n                    documentNativeApi.body.removeChild(documentNativeApi.getElementById(inputElement.id) as Node);\n                },\n                {once: true}\n            );\n\n            if (rejectOnCancel) {\n                window.addEventListener(\n                    'focus',\n                    () => {\n                        setTimeout(() => {\n                            if (!lock && documentNativeApi.getElementById(inputElement.id)) {\n                                reject(new Error('file upload on blur - no file selected'));\n                                documentNativeApi.body.removeChild(documentNativeApi.getElementById(inputElement.id) as Node);\n                            }\n                        }, 300);\n                    },\n                    {once: true}\n                );\n            }\n\n            // open file select box\n            inputElement.click();\n        });\n    };\n\n    static compress = (\n        imageDataUrlSource: DataUrl,\n        orientation: DOC_ORIENTATION,\n        render: Renderer2,\n        ratio: number = 50,\n        quality: number = 50,\n        maxwidth: number = 0,\n        maxheight: number = 0\n    ): Promise<string> =>\n        new Promise(function (resolve, reject) {\n            quality = quality / 100;\n            ratio = ratio / 100;\n            const sourceImage = new Image();\n\n            // important for safari: we need to wait for onload event\n            sourceImage.onload = () => {\n                const canvas: HTMLCanvasElement = render.createElement('canvas');\n                const ctx: CanvasRenderingContext2D | null = canvas.getContext('2d');\n\n                if (!ctx) {\n                    return reject(`No canvas context available`);\n                }\n\n                let w = sourceImage.naturalWidth;\n                let h = sourceImage.naturalHeight;\n\n                if (!CSS.supports('image-orientation', 'from-image')) {\n                    if (orientation === DOC_ORIENTATION.Right || orientation === DOC_ORIENTATION.Left) {\n                        const t = w;\n                        w = h;\n                        h = t;\n                    }\n                }\n\n                let xratio = maxwidth ? maxwidth / w : 1;\n                let yratio = maxheight ? maxheight / h : 1;\n                ratio = Math.min(ratio, xratio, yratio);\n                canvas.width = w * ratio;\n                canvas.height = h * ratio;\n\n                const TO_RADIANS = Math.PI / 180;\n\n                if (CSS.supports('image-orientation', 'from-image') || orientation === DOC_ORIENTATION.Up) {\n                    ctx.drawImage(sourceImage, 0, 0, canvas.width, canvas.height);\n                } else if (orientation === DOC_ORIENTATION.Right) {\n                    ctx.save();\n                    ctx.rotate(90 * TO_RADIANS);\n                    ctx.translate(0, -canvas.width);\n                    ctx.drawImage(sourceImage, 0, 0, canvas.height, canvas.width);\n                    ctx.restore();\n                } else if (orientation === DOC_ORIENTATION.Left) {\n                    ctx.save();\n                    ctx.rotate(-90 * TO_RADIANS);\n                    ctx.translate(-canvas.width, 0);\n                    ctx.drawImage(sourceImage, 0, 0, canvas.height, canvas.width);\n                    ctx.restore();\n                } else if (orientation === DOC_ORIENTATION.Down) {\n                    ctx.save();\n                    ctx.rotate(180 * TO_RADIANS);\n                    ctx.translate(-canvas.width, -canvas.height);\n                    ctx.drawImage(sourceImage, 0, 0, canvas.width, canvas.height);\n                    ctx.restore();\n                } else {\n                    // no orientation value found - same as default UP\n                    ctx.drawImage(sourceImage, 0, 0, canvas.width, canvas.height);\n                }\n\n                const mime = imageDataUrlSource.substr(5, imageDataUrlSource.split(';')[0].length - 5);\n                // TODO test on mime\n                const result = canvas.toDataURL(mime, quality);\n\n                resolve(result);\n            };\n\n            sourceImage.onerror = e => reject(e);\n            sourceImage.src = imageDataUrlSource;\n        });\n\n    static byteCount = (imgString: DataUrl): number => encodeURI(imgString).split(/%..|./).length - 1;\n\n    static getImageMaxSize = async (maxSizeMb: number, debugMode: boolean, render: Renderer2): Promise<DataUrl> => {\n        const MAX_TRIES = 10;\n\n        const bytesToMB = (bytes: number) => (bytes / 1024 / 1024).toFixed(2);\n\n        if (debugMode) {\n            console.debug('NgxImageCompress - Opening upload window');\n        }\n\n        let myFile: UploadResponse = (await ImageCompress.uploadFile(render, false)) as UploadResponse;\n\n        let compressedFile;\n\n        for (let i = 0; i < MAX_TRIES; i++) {\n            const previousSize = ImageCompress.byteCount(myFile.image);\n            compressedFile = await ImageCompress.compress(myFile.image, myFile.orientation, render, 50, 100);\n            const newSize = ImageCompress.byteCount(compressedFile);\n            console.debug('NgxImageCompress -', 'Compression from', bytesToMB(previousSize), 'MB to', bytesToMB(newSize), 'MB');\n            if (newSize >= previousSize) {\n                if (i === 0) {\n                    if (debugMode) {\n                        console.debug(\n                            'NgxImageCompress -',\n                            \"File can't be reduced at all - returning the original\",\n                            bytesToMB(previousSize),\n                            'MB large'\n                        );\n                    }\n                    throw myFile.image;\n                } else {\n                    if (debugMode) {\n                        console.debug(\n                            'NgxImageCompress -',\n                            \"File can't be reduced more - returning the best we can, which is \",\n                            bytesToMB(previousSize),\n                            'MB large'\n                        );\n                    }\n                    throw myFile.image;\n                }\n            } else {\n                if (newSize < maxSizeMb * 1024 * 1024) {\n                    if (debugMode) {\n                        console.debug('NgxImageCompress -', 'Here your file', bytesToMB(newSize), 'MB large');\n                    }\n                    return compressedFile;\n                } else if (i === 9) {\n                    if (debugMode) {\n                        console.debug(\n                            'NgxImageCompress -',\n                            \"File can't reach the desired size after\",\n                            MAX_TRIES,\n                            'tries. Returning file ',\n                            bytesToMB(previousSize),\n                            'MB large'\n                        );\n                    }\n                    throw myFile.image;\n                }\n            }\n            if (debugMode) {\n                console.debug('NgxImageCompress -', 'Reached', bytesToMB(newSize), 'MB large. Trying another time after', i + 1, 'times');\n            }\n            myFile.image = compressedFile;\n        }\n        if (debugMode) {\n            console.debug('NgxImageCompress - Unexpected error');\n        }\n        throw '';\n    };\n}\n","import {Injectable, Renderer2, RendererFactory2} from '@angular/core';\nimport {ImageCompress} from './image-compress';\nimport {DOC_ORIENTATION} from './models/DOC_ORIENTATION';\nimport {UploadResponse} from './models/upload-response';\nimport {DataUrl} from './models/data-url';\n\n@Injectable({\n    providedIn: 'root',\n})\nexport class NgxImageCompressService {\n    private readonly render: Renderer2;\n\n    public DOC_ORIENTATION = DOC_ORIENTATION;\n\n    constructor(rendererFactory: RendererFactory2) {\n        this.render = rendererFactory.createRenderer(null, null);\n    }\n\n    /**\n     * helper to evaluate the compression rate\n     * @param imgString the image in base64 string format\n     */\n    public byteCount(image: DataUrl) {\n        return ImageCompress.byteCount(image);\n    }\n\n    /**\n     * Get the correct Orientation value from image tags\n     */\n    public getOrientation(file: File): Promise<DOC_ORIENTATION> {\n        return ImageCompress.getOrientation(file);\n    }\n\n    /**\n     * return a promise with the new image data and image orientation\n     * Nothing happen if no file have been selected\n     */\n    public uploadFile(): Promise<UploadResponse> {\n        return ImageCompress.uploadFile(this.render, false) as Promise<UploadResponse>;\n    }\n\n    /**\n     * return a promise with an array of image data and image orientation\n     * Nothing happen if no files have been selected\n     */\n    public uploadMultipleFiles(): Promise<UploadResponse[]> {\n        return ImageCompress.uploadFile(this.render, true) as Promise<UploadResponse[]>;\n    }\n\n    /**\n     * return a promise with the new image data and image orientation\n     * the promise will reject if no file have been selected\n     */\n    public uploadFileOrReject(): Promise<UploadResponse> {\n        return ImageCompress.uploadFile(this.render, false, true) as Promise<UploadResponse>;\n    }\n\n    /**\n     * return a promise with an array of image data and image orientation\n     * the promise will reject if no files have been selected\n     */\n    public uploadMultipleFilesOrReject(): Promise<UploadResponse[]> {\n        return ImageCompress.uploadFile(this.render, true, true) as Promise<UploadResponse[]>;\n    }\n\n    /**\n   * perform a compression from the given DataUrl (string), provided by the uploadFile, or uploadMultipleFiles method\n   *\n   *\n   | Parameter   | Type   | Description                                                                       |\n   | ----------- | ------ | --------------------------------------------------------------------------------- |\n   | image       | string | DataUrl (string) representing the image                                           |\n   | orientation | number | EXIF Orientation value using the DOC_ORIENTATION enum value                       |\n   | ratio       | number | Maximum scale factor as a percentage (optional, default: 50) <sup>[1](#fn1)</sup> |\n   | quality     | number | JPEG quality factor as a percentage (optional, default: 50) <sup>[2](#fn2)</sup>  |\n   | maxwidth    | number | Maximum width in pixels if you need to resize (optional, default: 0 - no resize)  |\n   | maxheight   | number | Maximum height in pixels if you need to resize (optional, default: 0 - no resize) |\n   */\n    public compressFile(\n        image: DataUrl,\n        orientation: DOC_ORIENTATION,\n        ratio: number = 50,\n        quality: number = 50,\n        maxWidth: number = 0,\n        maxHeight: number = 0\n    ): Promise<DataUrl> {\n        return ImageCompress.compress(image, orientation, this.render, ratio, quality, maxWidth, maxHeight);\n    }\n\n    /**\n     * Most simple function to use here.\n     * Perform an upload and return an image dataUrl (string format) with a maximum size, given in *MegaBytes*\n     * If the size can't be reached, the best that can be reached will be returned in promise *rejection*\n     * Put debugMode to true if you have some trouble to print some help using console.debug\n     */\n    public uploadAndGetImageWithMaxSize(maxSizeMb: number = 1, debugMode = false): Promise<DataUrl> {\n        return ImageCompress.getImageMaxSize(maxSizeMb, debugMode, this.render);\n    }\n}\n","/*\n * Public API Surface of ngx-image-compress\n */\n\nexport * from './lib/ngx-image-compress.service';\nexport * from './lib/models/DOC_ORIENTATION';\nexport * from './lib/models/upload-response';\nexport * from './lib/models/data-url';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}