All files / roosterjs-content-model-plugins/lib/imageEdit/utils generateDataURL.ts

96.67% Statements 29/30
85.71% Branches 24/28
100% Functions 1/1
96.67% Lines 29/30

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 731x                           1x 4x 4x                           36x 4x 4x 4x 4x 4x 4x 4x 4x 4x   4x 4x     4x 4x 8x 4x 4x   4x 4x 4x 4x 4x 4x 4x                         4x    
import { getGeneratedImageSize } from './generateImageSize';
import type { ImageMetadataFormat } from 'roosterjs-content-model-types';
 
/**
 * @internal
 * Generate new dataURL from an image and edit info
 * @param image The image to generate data URL from. It is supposed to have original src loaded
 * @param editInfo Edit info of the image
 * @returns A BASE64 encoded string with image prefix that represents the content of the generated image.
 * If there are rotate/crop/resize info in the edit info, the generated image will also reflect the result.
 * It is possible to throw exception since the original image may not be able to read its content from
 * the code, so better check canRegenerateImage() of the image first.
 * @throws Exception when fail to generate dataURL from canvas
 */
export function generateDataURL(image: HTMLImageElement, editInfo: ImageMetadataFormat): string {
    const generatedImageSize = getGeneratedImageSize(editInfo);
    Iif (!generatedImageSize) {
        return '';
    }
 
    const {
        angleRad,
        widthPx,
        heightPx,
        bottomPercent,
        leftPercent,
        rightPercent,
        topPercent,
        naturalWidth,
        naturalHeight,
    } = editInfo;
    const angle = angleRad || 0;
    const left = leftPercent || 0;
    const right = rightPercent || 0;
    const top = topPercent || 0;
    const bottom = bottomPercent || 0;
    const nHeight = naturalHeight || image.naturalHeight;
    const nWidth = naturalWidth || image.naturalHeight;
    const width = widthPx || image.clientWidth;
    const height = heightPx || image.clientHeight;
 
    const imageWidth = nWidth * (1 - left - right);
    const imageHeight = nHeight * (1 - top - bottom);
 
    // Adjust the canvas size and scaling for high display resolution
    const devicePixelRatio = window.devicePixelRatio || 1;
    const canvas = document.createElement('canvas');
    const { targetWidth, targetHeight } = generatedImageSize;
    canvas.width = targetWidth * devicePixelRatio;
    canvas.height = targetHeight * devicePixelRatio;
 
    const context = canvas.getContext('2d');
    Eif (context) {
        context.scale(devicePixelRatio, devicePixelRatio);
        context.translate(targetWidth / 2, targetHeight / 2);
        context.rotate(angle);
        context.scale(editInfo.flippedHorizontal ? -1 : 1, editInfo.flippedVertical ? -1 : 1);
        context.drawImage(
            image,
            nWidth * left,
            nHeight * top,
            imageWidth,
            imageHeight,
            -width / 2,
            -height / 2,
            width,
            height
        );
    }
 
    return canvas.toDataURL('image/png', 1.0);
}