Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   canvas - изменить цвет картинки (https://javascript.ru/forum/misc/76157-canvas-izmenit-cvet-kartinki.html)

Роман Андреевич 10.12.2018 09:32

canvas - изменить цвет картинки
 
Коллеги, доброго времени суток, начал разбирать canvas и немного тупить начал, одновременно.

Стоит задача следующая, получаю картинку не суть как, она приходит и нормально. Картинка png - прозрачный фон + какая-то фигура одно цвета - желтого rgba(255, 255, 0, 1).

При клике на нее, я получаю данные какие мне нужно, но мне нужно ее перекрасить в другой цвет. например - rgba(228, 60 , 30 ,1);

Как это сделать?

let cvs = document.getElementById('canvas');
let ctx = cvs.getContext('2d');

		function resize() {

			cvs.width = document.documentElement.clientWidth;
			cvs.height = document.documentElement.clientHeight;

		};

		resize();

		let img = new Image();
		img.src = 'images/1.png';

		img.style.display = 'block';

		img.addEventListener('load', () => {

			let options = {

				sX: 0,
				sY: 0,
				sWidth: 400,
				sHeight: 400

			}

			ctx.drawImage(img, options.sX, options.sY, options.sWidth, options.sHeight);

		});

		cvs.addEventListener('click', (e) => {

			// console.log(ctx.getImageData(e.offsetX, e.offsetY, 1, 1).data);

			let imageData = ctx.getImageData(0,0, cvs.width, cvs.height);

			imageData.data[0] = 228;
			imageData.data[1] = 60;
			imageData.data[2] = 30;
			imageData.data[3] = 225;

			ctx.putImageData(imageData, 0, 0);

		}, false);

		canvas.addEventListener('contextmenu', (e) => {

			e.preventDefault();

		});


В примере выше не работает никак. Заранее благодарю.

рони 10.12.2018 09:55

Роман Андреевич,
цикл по всему массиву точек вместо строки 39 - 42

рони 10.12.2018 10:08

Роман Андреевич,
let imageData = ctx.getImageData(0,0, cvs.width, cvs.height);
 let pix  = imageData.data;
  for (let i = 0, n = pix.length; i < n; i += 4) {
    if(pix[i] == 255 && pix[i + 1] == 255 && pix[i + 2] == 0) {
    pix[i]     = 228;
    pix[i + 1] = 60;
    pix[i + 2] = 30;
    }

  }

Роман Андреевич 10.12.2018 10:18

рони, спасибо. Работает. ))))

Роман Андреевич 10.12.2018 10:33

рони, точно, сейчас разобрал imageData, там же массив)))))) В любом случае спасибо

Alexandroppolus 10.12.2018 11:08

понедельничные зарисовки на тему Uint32Array
https://jsfiddle.net/alexandroppolus/wc7r4jbf/

var imageData = ctx.getImageData(0, 0, cv.width, cv.height);
  var pix  = new Uint32Array(imageData.data.buffer);
  
  var replacedColor = 0xff00ffff;
  var resultColor = 0xff1e3ce4;

  for (var i = 0, n = pix.length; i < n; ++i) {
    if(pix[i] == replacedColor) {
    	pix[i] = resultColor;
    }

  }
  ctx.putImageData(imageData, 0, 0);

Роман Андреевич 10.12.2018 11:17

рони, в продолжении темы - на канвас добавляем по картинке при клике на кнопку:

let cvs = document.getElementById('canvas');
let button = document.getElementById('button');
let ctx = cvs.getContext('2d');

let colors = [[255,255,0],[228,60,30],[53,198,29]];
let colorLength = colors.length;
let flag = false;

let images = [];
let options = {

	width: 400,
	height: 400

};

function resize() {

	cvs.width = document.documentElement.clientWidth;
	cvs.height = document.documentElement.clientHeight;

};

function addImage(e) {
	
	if (images.length === colorLength) {

		console.log('больше нельзя добавлять картинок');
		return;

	}

	console.log('Добавили новую картинку');

	let img = new Image();
	img.src = 'images/1.png';

	let color = colors.pop();
	console.log(color);

	img.addEventListener('load', () => {

		images.push(img);

                let x = 0;
		
		switch (images.length) {

			case 2:
				x = 400;
				break;
			case 3: 
				x = 800;
				break;
			default:
				x = 0;
		}

		ctx.drawImage(img, x, 0, options.width, options.height);

		let imageData = ctx.getImageData(0,0, img.width, img.height);
		let data = imageData.data;

		for (let i = 0, n = data.length; i < n; i += 4) {
			
			if (data[i] !== 0 && data[i + 1] !== 0) {

				data[i] = color[0];
				data[i + 1] = color[1];
				data[i + 2] = color[2];

			}

		}
	     
	    ctx.putImageData(imageData, 0, 0);

	});

}

resize();

button.addEventListener('click', addImage);


colors - это массив, который содержит цвета (ну для примера). Далее нам нужно добавить несколько картинок. Тип у них одинаковый (прозрачный фон и заливка фигуры желтая). но на выходе нужно каждую новую картинку раскрасить в новый цвет. Из массива colors берем последний элемент (первый дольше, да и разницы нет). И красим картинку. С первой картинкой все в порядке. но дальше уже хуже. Я как понимаю что let imageData = ctx.getImageData(0,0, img.width, img.height); берет data не текущей картинки которую мы вставили, а уже существующей. Как каждую новую картинку раскрашивать в нужный цвет???

Alexandroppolus 10.12.2018 11:26

ты каждый раз берешь левый верхний угол

надо
ctx.getImageData(x,0, img.width, img.height);
ctx.putImageData(imageData, x, 0);

Alexandroppolus 10.12.2018 11:27

и да
resize() будет убивать всю картинку

Роман Андреевич 10.12.2018 11:37

Alexandroppolus, не работает. Сначала картинка должна быть зеленая, потом красная потом желтая. Но первая зеленая, когда появляется вторая, первая становится красная, вторая желтая. Когда третья появляется то все картинки становятся желтые.)))) я поменял x но все равно та же история


Часовой пояс GMT +3, время: 12:57.