Быстрый способ изменить размер изображения в браузере? - PullRequest
0 голосов
/ 25 марта 2019

У меня есть холст 600 x 400 пикселей, который возвращает ImageData с длиной данных 960 000 (600 * 400 * 4).Есть ли способ уменьшить и ширину, и высоту, скажем, в 10 раз, я хотел бы получить в результате ImageData, длина данных которого составляет 9600 (60 * 40 * 4).

const canvas = document.getElementsByTagName("canvas")[0]
var ctx = canvas.getContext("2d");
const origImageData = ctx.getImageData(0, 0, canvas.width, canvas.height)
origImageData
// => ImageData {data: Uint8ClampedArray(960000), width: 600, height: 400}
const smallImageData = downscale(origImageData, 60, 40);
smallImageData
// => ImageData {data: Uint8ClampedArray(9600), width: 60, height: 40}

Мне нужно получить ImageDataмассив .data для дальнейших манипуляций.Этот метод будет вызываться в цикле, поэтому было бы хорошо, если бы он был быстрым.

Редактировать Это предлагаемый подход, но я не уверен, что он правильный:

var canvas2 = document.createElement('canvas');
canvas2.width = canvas.width/10;
canvas2.height = canvas.height/10;
var ctx2 = canvas2.getContext('2d');
// Step that I found confusing
// Is the new image data being created?
ctx2.putImageData(origImageData, 0, 0);
// Which image data I'm getting here resized or part of original ?
ctx2.getImageData(0,0,  canvas2.width, canvas2.height)

Редактировать 2 Кажется, он не работает, небольшой холст не изменен, а только обрезан https://codepen.io/bobiblazeski/full/drrQoB

1 Ответ

1 голос
/ 25 марта 2019

После некоторой возни я нашел решение, используя этот ответ в качестве отправной точки.По сути, вы можете просто нарисовать больший холст на меньшем холсте, а затем получить из него ImageData.

const bigCanvas = document.getElementById("big");
const bigContext = bigCanvas.getContext("2d");        
const smallContext = document.getElementById("small").getContext("2d");         
smallContext.scale(0.5, 0.5);
smallContext.drawImage(bigCanvas, 0, 0);        
const smallImageData = smallContext.getImageData(0, 0, bigCanvas.width, bigCanvas.height);

Вот кодовый код в качестве доказательства того, что полученные данные изображения представляют собой уменьшенную версиюисходный холст, а не просто фрагмент из него.

Big Small Resized

Если вы хотите изменить размер в цикле, очистите холст назначения перед вызовом drawImage codepen .

const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));

const bigCanvas = document.getElementById("big");
const bigContext = bigCanvas.getContext("2d");
const smallCanvas = document.getElementById("small");
const smallContext = smallCanvas.getContext("2d"); 
const otherCanvas = document.getElementById("other");
const otherContext = otherCanvas.getContext("2d");

function getImage(i) {
    bigContext.clearRect(0, 0, bigCanvas.width, bigCanvas.height);
    bigContext.fillRect(((i+0)%5)*100,   0, 100, 100);
    bigContext.fillRect(((i+1)%5)*100, 100, 100, 100);
    bigContext.fillRect(((i+2)%5)*100, 200, 100, 100);    
    bigContext.fillRect(((i+3)%5)*100, 100, 100, 100);
    bigContext.fillRect(((i+4)%5)*100,   0, 100, 100);
    bigContext.fillRect(((i+0)%5)*100, 200, 100, 100);    

    smallContext.clearRect(0, 0, smallCanvas.width, smallCanvas.height);
    smallContext.drawImage(bigCanvas, 0, 0, smallCanvas.width, smallCanvas.height);
    const smallImageData = smallContext.getImageData(0,0, 
        bigCanvas.width, bigCanvas.height);

    otherContext.putImageData(smallImageData, 0, 0);
};

window.addEventListener("DOMContentLoaded", function() {
    var i = 0;
    setInterval(() => {
        console.log(i);
        getImage(i++);
    }, 3000);
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...