Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

why Why did I use getImageData() for more than 1 minute? #302

Open
aajiejie opened this issue Nov 26, 2022 · 3 comments
Open

why Why did I use getImageData() for more than 1 minute? #302

aajiejie opened this issue Nov 26, 2022 · 3 comments

Comments

@aajiejie
Copy link

When I use getImageData(), I have to wait for a long time to get data, which is unbearable. Why is this? ImgWH=360,pixelRatio=3 and the image pixel is 360 * 360
`const wh = imgWH * pixelRatio;

context.getImageData(0, 0, wh, wh).then(imageData => {

....

}`

@SvetlozarValchev
Copy link

Same issue, it takes about a minute for getImageData to resolve with a 300x600 canvas

@aajiejie
Copy link
Author

aajiejie commented May 2, 2023

Same issue, it takes about a minute for getImageData to resolve with a 300x600 canvas

I have two solutions to solve it

  1. Further reduce until you can tolerate the time
  2. Divide the pixels of the canvas into blocks and process them one by one

@FengFuLiu
Copy link

getImageDataInBlocks = async (context: CanvasRenderingContext2D, pixelWidth: number, pixelHeight: number, blockWidth: number, blockHeight: number) => {
	const totalBlocksX = Math.ceil(pixelWidth / blockWidth);
	const totalBlocksY = Math.ceil(pixelHeight / blockHeight);
	const imageDataArray = new Array(pixelWidth * pixelHeight * 4).fill(0);

	for (let blockY = 0; blockY < totalBlocksY; blockY++) {
		for (let blockX = 0; blockX < totalBlocksX; blockX++) {
			const x = blockX * blockWidth;
			const y = blockY * blockHeight;

			const currentBlockWidth = Math.min(blockWidth, pixelWidth - x);
			const currentBlockHeight = Math.min(blockHeight, pixelHeight - y);

			// 获取当前区块的图像数据
			const blockImageData = await context.getImageData(x, y, currentBlockWidth, currentBlockHeight);
			const dataArr = Object.values(blockImageData.data); 

			for (let row = 0; row < currentBlockHeight; row++) {
				const rowStart = row * currentBlockWidth * 4;
				const targetRowStart = ((y + row) * pixelWidth + x) * 4;

				// 将当前行数据插入到目标数组中
				for (let i = 0; i < currentBlockWidth * 4; i++) {
					imageDataArray[targetRowStart + i] = dataArr[rowStart + i];
				}
			}
		}
	}

	return imageDataArray;
}

				let data =  await this.getImageDataInBlocks(context, pixelWidth, pixelHeight, 150, 150);

this function faster

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants