JS FAST에서 이미지 크기 조정! (브라우저 멀티스레딩 사용)

오늘은 약간의 캔버스 지식을 염두에 두고 오프스크린 캔버스에 뛰어들 것입니다. 필요한 경우 다른 리소스를 확인하고 Blob, image_data(캔버스), 비트맵 이미지 및 data-url( base64), 이를 사용하여 메인 스레드에서 JS 이미지 필터( )를 렌더링할 수 있으며 잘 작동합니다! 또한 코드를 확인하십시오. 그렇게 길지 않고 주석이 잘 달려 있습니다. 내가 빌드한 프로젝트(https://pixa.pics/)는 https://www.npmjs.com/package/workerpool을 사용하여 모든 항목을 작업자에게 전파합니다...

1) 비트맵 이미지용으로 만든 캔버스로 전송할 비트맵 이미지를 만듭니다.
2) blob 파일(파일과 같은 객체)을 생성할 때 선택한 파일 형식으로 래스터 이미지를 변환합니다.
3) 파일과 같은 객체를 base64로 인코딩된 이미지(data:image/png;base64,...및 일부 base64)인 dataurl로 변환합니다.
이것은 마법이다

// CONST:
// imgd_data (you get img_data using a canvas, please get familiar with canvas)
// no_transparent (Boolean to know which file format to use)
// pxl_width (Simply width of the image)
// pxl_height (Simply height of the image)
// resize_width (Which size of width will it get at the end?)

try { // Can work in Web Worker so you can run it on a CPU thread different from the main one which doesn't freeze the UI

    var imgd = null;
    // imgd = new ImageData(pxl_width, pxl_height);
    // imgd.data = imgd_data;

    var canvas = new OffscreenCanvas(pxl_width, pxl_height);
    var ctx = canvas.getContext('2d');
    imgd = ctx.getImageData(0, 0, pxl_width, pxl_height);


    var resize_ratio = resize_width / pxl_width;
    var resizeWidth = parseInt(pxl_width * resize_ratio);
    var resizeHeight = parseInt(pxl_height * resize_ratio);

    var canvas2 = new OffscreenCanvas(resizeWidth, resizeHeight);
    var ctx2 = canvas2.getContext("bitmaprenderer"); // "bitmaprenderer" context is available in web worker which isn't true for "2d" context

    // Of course with a bitmaprenderer context we may need to create a bitmap image, this is how we do :
    // 1) We create a Bitmap Image which will be transferred onto our canvas made for bitmap images
    // 2) We convert the raster image into a file format we choose when we create a blob file (a file-like object)
    // 3) We convert that file-like object into a dataurl which is base64 encoded image (data:image/png;base64,...and some base64)
    // THIS IS MAGIC
    return createImageBitmap(imgd, {
        premultiplyAlpha: 'none',
        colorSpaceConversion: 'none',
        resizeWidth: resizeWidth,
        resizeHeight: resizeHeight,
        resizeQuality: "pixelated", // One of pixelated, low (default), medium, or high
    }).then((btmp_i) => {

        // And at once, we resized it before transfering it now onto the canvas context responsible for exporting it
        ctx2.transferFromImageBitmap(btmp_i);

        var blob_params = no_transparent ? {type: "image/jpeg", quality: 0.3}: {type: "image/png"}; // We can also export the image in webp format but just wrap it into a try catch because it isn't supported everywhere

        // We call the canvas of our second context (canvas2) and ask the browser to create a blob (which is a file-like object of immutable, raw data)
        return ctx2.canvas.convertToBlob(blob_params).then((blob) => {

            // With it, we read the blob file as a data url you know (data:image/png;base64,...and some base64)
            function blob_to_base64(blob) { 
              return new Promise((resolve, _) => { 
                var reader = new FileReader();
                reader.onloadend = () => resolve(reader.result);
                reader.readAsDataURL(blob);
              })
            }

            return blob_to_base64(blob).then((data_url) => { // This we get a promise so we can call ".then()" to this function

                 return data_url;
            });
        });
    });

}catch(e) { // Hopefully if OffscreenCanvas or such isn't supported we can use the classical method but it won't work in Web Worker my friend

    var canvas = document.createElement("canvas");
    canvas.width = pxl_width;
    canvas.height = pxl_height;
    var ctx = canvas.getContext('2d');

    var imgd = null;
    // imgd = new ImageData(pxl_width, pxl_height);
    // imgd.data = imgd_data;
    // ctx.putImageData(image_data, 0, 0);

    var resize_ratio = resize_width / pxl_width;
    var resizeWidth = parseInt(pxl_width * resize_ratio);
    var resizeHeight = parseInt(pxl_height * resize_ratio);

    // THIS IS NOT MAGIC, we just draw an image on our simple secondary canvas (but again it doesn't work off the main thread since it can't work in Web Worker)
    var canvas2 = document.createElement("canvas");
    canvas2.width = resizeWidth;
    canvas2.height = resizeHeight;
    var ctx2 = canvas2.getContext("2d");
    ctx2.drawImage(canvas, 0, 0, resizeWidth, resizeHeight);

    if(no_transparent){

        return canvas2.toDataURL("image/jpeg", 0.3); 
    }else {

        return canvas2.toDataURL("image/png");
    }

    // We can also export the image in webp format but just wrap it into a try catch because it isn't supported everywhere
}

// USEFULL TIPS: Use https://www.npmjs.com/package/workerpool combined with THIS ENSOULEMENT:
new Function(`return async function(param1, param2){}`)()(param1, param2)

좋은 웹페이지 즐겨찾기