programing

캔버스를 사용하지 않고 JavaScript에서 Base-64 이미지 크기 조정

nasanasas 2020. 12. 30. 08:15
반응형

캔버스를 사용하지 않고 JavaScript에서 Base-64 이미지 크기 조정


HTML 요소를 사용하지 않고 JavaScript에서 그림 크기를 조정하는 방법이 필요합니다.

내 모바일 HTML 앱은 사진을 찍은 다음 base64 문자열로 변환합니다. 그 후에 저장 공간을 절약하기 위해 API로 보내기 전에 크기를 조정해야합니다.

캔버스 요소를 사용하여 크기를 조정하는 다른 방법을 찾고 있습니다. 방법이 있습니까?


메인 HTML이 영향을받지 않도록하는 방법은 DOM 트리에서 제외되는 오프 스크린 캔버스를 만드는 것입니다.

이것은 이미지 데이터를 인코딩하기위한 비트 맵 버퍼와 네이티브 컴파일 코드를 제공합니다. 다음을 수행하는 것은 간단합니다.

function imageToDataUri(img, width, height) {

    // create an off-screen canvas
    var canvas = document.createElement('canvas'),
        ctx = canvas.getContext('2d');

    // set its dimension to target size
    canvas.width = width;
    canvas.height = height;

    // draw source image into the off-screen canvas:
    ctx.drawImage(img, 0, 0, width, height);

    // encode image to data-uri with base64 version of compressed image
    return canvas.toDataURL();
}

PNG (기본값)와 다른 형식을 생성하려면 다음과 같이 유형을 지정하십시오.

return canvas.toDataURL('image/jpeg', quality);  // quality = [0.0, 1.0]

참고로 가치 CORS의 제한이 적용 toDataURL().

앱이 base64로 인코딩 된 이미지 만 제공하는 경우 (base64 데이터가있는 data-uri라고 가정합니까?) 먼저 이미지를 "로드"해야합니다.

var img = new Image;

img.onload = resizeImage;
img.src = originalDataUriHere;

function resizeImage() {
    var newDataUri = imageToDataUri(this, targetWidth, targetHeight);
    // continue from here...
}

소스가 순수한 base-64 문자열 인 경우 단순히 헤더를 추가하여 데이터 URI로 만듭니다.

function base64ToDataUri(base64) {
    return 'data:image/png;base64,' + base64;
}

image/png부분을 ​​base64 문자열이 나타내는 유형으로 바꾸기 만하면됩니다 (즉, 선택적 인수로 만듭니다).


Ken의 대답은 정답이지만 그의 코드는 작동하지 않습니다. 나는 그것에 약간의 조정을했고 이제 완벽하게 작동합니다. 데이터 URI 크기를 조정하려면 다음을 수행하십시오.

// Takes a data URI and returns the Data URI corresponding to the resized image at the wanted size.
function resizedataURL(datas, wantedWidth, wantedHeight)
    {
        // We create an image to receive the Data URI
        var img = document.createElement('img');

        // When the event "onload" is triggered we can resize the image.
        img.onload = function()
            {        
                // We create a canvas and get its context.
                var canvas = document.createElement('canvas');
                var ctx = canvas.getContext('2d');

                // We set the dimensions at the wanted size.
                canvas.width = wantedWidth;
                canvas.height = wantedHeight;

                // We resize the image with the canvas method drawImage();
                ctx.drawImage(this, 0, 0, wantedWidth, wantedHeight);

                var dataURI = canvas.toDataURL();

                /////////////////////////////////////////
                // Use and treat your Data URI here !! //
                /////////////////////////////////////////
            };

        // We put the Data URI in the image's src attribute
        img.src = datas;
    }
// Use it like that : resizedataURL('yourDataURIHere', 50, 50);

Pierrick Martellière가 가장 좋은 대답입니다. 비동기 함수로 구현해야한다는 점을 지적하고 싶었습니다. 그러면 다음과 같은 작업을 수행 할 수 있습니다.

var newDataUri = await resizedataURL(datas,600,600);

다음 단계로 이동하기 전에 함수의 결과를 기다립니다. 코드를 작성하는 더 깨끗한 방법입니다. 다음은 약간의 편집이있는 Pierrick의 기능입니다.

// Takes a data URI and returns the Data URI corresponding to the resized image at the wanted size.
function resizedataURL(datas, wantedWidth, wantedHeight){
    return new Promise(async function(resolve,reject){

        // We create an image to receive the Data URI
        var img = document.createElement('img');

        // When the event "onload" is triggered we can resize the image.
        img.onload = function()
        {        
            // We create a canvas and get its context.
            var canvas = document.createElement('canvas');
            var ctx = canvas.getContext('2d');

            // We set the dimensions at the wanted size.
            canvas.width = wantedWidth;
            canvas.height = wantedHeight;

            // We resize the image with the canvas method drawImage();
            ctx.drawImage(this, 0, 0, wantedWidth, wantedHeight);

            var dataURI = canvas.toDataURL();

            // This is the return of the Promise
            resolve(dataURI);
        };

        // We put the Data URI in the image's src attribute
        img.src = datas;

    })
}// Use it like : var newDataURI = await resizedataURL('yourDataURIHere', 50, 50);

For more details you can check MDN Docs : https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Promise


Yes, you can. These solutions good for resizing not just converting image to base64.

  1. You can convert js file to image bitmap by jpg-js.And you can resize only by this lib, but in a case of resizing from very large image to very small, quality will be very bad.Best way for high-res images is to convert file to bitmap by jpg-js and then resize this bitmap by Pica lib.
  2. You can get image data from a file by jpg-js (or draw an image on canvas)and then resize canvasImageData by resizing lib pica. (good for High-resolution images, without canvas size restriction)
  3. You can use offscreen canvas, without attaching the canvas to a body, and resize an image. This solution will be faster but will be the worse solution for high-resolution images, for example 6000x6000 pixels. In that case, result canvas can be with bad quality or just empty, or browser can fall with memory limit exception. (good for normal and small images)

Jpg-js and Pica will not use dom elements at all. These libs are working only with image data, without dom elements (canvas and image).

About the canvas, size restriction see this post


You can use a raw Base64 image manipulation as shown here.

Looks difficult ( and for png only ) and why many choose to use canvas

http://blog.calyptus.eu/seb/2009/05/png-parser-in-javascript/

ReferenceURL : https://stackoverflow.com/questions/20958078/resize-a-base-64-image-in-javascript-without-using-canvas

반응형