Форум программистов, компьютерный форум, киберфорум
JavaScript: HTML5 Canvas
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.56/9: Рейтинг темы: голосов - 9, средняя оценка - 4.56
 Аватар для blbulyan
12 / 10 / 3
Регистрация: 31.10.2017
Сообщений: 126

Не получается получить цвет пикселя в canvas используя getImageData

26.08.2019, 10:03. Показов 1823. Ответов 2

Студворк — интернет-сервис помощи студентам
Проблему удалось кратко описать в заголовке, тут я распишу её более подробней, есть вот такой код:
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
var timerId = 0;
var counter = 0;
function randomInteger(min, max) {
  return Math.floor(Math.random() * (max - min) ) + min;
}
function ShowRandomCircle(){
    Clear();
    let MyCanvas = document.getElementById('mycanvas');
    let c = MyCanvas.getContext('2d');
    let Radius = randomInteger(20, 50);
    let Colours = ['red', 'blue', 'green'];
    let CelectedColour = Colours[randomInteger(0, 3)];
    c.beginPath();
    c.fillStyle = Colours[randomInteger(0, 3)];
    switch(randomInteger(1, 4)){
        case 1:{//круг
            c.arc(randomInteger(Radius, MyCanvas.width+1 - Radius), randomInteger(Radius, MyCanvas.height+1 - Radius), Radius, 0, 2*Math.PI);
            c.stroke();
            c.fill();
            break;
        }
        case 2:{//квадрат
            let a = randomInteger(20, 50);
            c.fillRect(randomInteger(0, MyCanvas.width+1 - a), randomInteger(0, MyCanvas.height+1 - a), a, a);
            break;
        }
        case 3://треугольник
            let xybegin = [randomInteger(0, MyCanvas.width+1), randomInteger(0, MyCanvas.height+1)];
            let xy2 = [randomInteger(xybegin[0]+5, xybegin[0]+100), randomInteger(xybegin[1]+5, xybegin[1]+100)];
            c.moveTo(xybegin[0], xybegin[1]);
            c.lineTo(xy2[0], xy2[1]);
            c.lineTo(randomInteger(xy2[0]+5, xy2[0]+100), randomInteger(xy2[1]+5, xy2[1]+100));
            c.closePath();
            c.stroke();
            c.fill();
            break;
    }
    
}
function Start(){
    counter = 0;
    timerId = setInterval(ShowRandomCircle, document.getElementById('setinterval').value);
}
function ModifyInterval(){
    Stop();
    Start(document.getElementById('setinterval').value);
}
function Stop(){
    clearTimeout(timerId);
}
function Clear(){
    var MyCanvas = document.getElementById('mycanvas');
    var c = MyCanvas.getContext('2d');
    c.clearRect(0, 0, MyCanvas.width, MyCanvas.height);
}
function MouseClickEvent(event){
    Stop();
    var MyCanvas = document.getElementById('mycanvas');
    var c = MyCanvas.getContext('2d');
    let ImgData = c.getImageData(event.clientX, event.clientY, 1, 1);
    if(((ImgData.data[0] != 0xFF) || (ImgData.data[1] != 0xFF) || (ImgData.data[2] != 0xFF)) && (ImgData.data[3] > 0)){
        document.getElementById('counter').innerHTML = ++counter;
    }
    Start(document.getElementById('setinterval').value);
}
HTML5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Мой первый проект Canvas</title>
    </head>
    <body>
        <canvas width="800" height="600" id="mycanvas" onclick="MouseClickEvent(event);"></canvas>
        <input type="button" value="Очистить" name="Clear" OnClick="Clear();">
        <input type="button" value="Стоп" name="Stop" OnClick="Stop();">
        <input type="button" value="Нарисовать" name="Start" OnClick="Start();">
        <input type="range" id="setinterval" name="setinterval" min="0" max="2000" value="200" step="10" onchange="ModifyInterval();">
        <div id="counter"></div>
        <script src="script/root.js"></script>
    </body>
</html>
Данная функция MouseClickEvent вызывается при клике мышкой по канвасу, (событие onclick), ну так вот, и getImageData возвращает практически везде нули, во всех составляющих цвета, но фон-то канваса у меня белый, но это ещё не всё, на канвасе отрисовываются в случайных местах случайные фигуры, ну и задача состоит в том, чтобы увеличить счётчик очков на единицу, если пользователь кликнул по появившейся фигуре, но это работает как-то некорректно, совсем некорректно, счётчик не всегда увеличивается на 1 если кликнуть по фигуре, в основном практически не увеличивается. Я не знаю почему, конечно извините за такой банальный вопрос, но всё же. Помогите пожалуйста.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
26.08.2019, 10:03
Ответы с готовыми решениями:

Как получить цвет пикселя в JavaFx Canvas
Собственно вопрос, как получить цвет одного пикселя из GraphicsContext. Такая простая вещь, а не могу нагуглить нормальное решение. Знаю...

Как в обьекте canvas определить цвет пикселя с заданными координатами
как в обьекте canvas определить цвет пикселя с заданными координатами? Или может существует обьект экран и через него можно определить...

Получить цвет пикселя
Подскажите, как получить цвет пикселя. Везде приводятся такие примеры работы с GetPixel: Bitmap myBitmap = new...

2
the hardway first
Эксперт JS
 Аватар для j2FunOnly
2475 / 1847 / 910
Регистрация: 05.06.2015
Сообщений: 3,610
26.08.2019, 10:26
Фон не белый, когда фон не установлен он имеет значения (0, 0, 0, 0) - последний 0 - это непрозрачность.
У вас напутано с интервалами, а при клике вы пытаетесь остановить интервал (для этого используйте clearInterval(), а не clearTimeout()), увеличить счетчик и запустить интервал, и в функции Start() у вас counter устанавливается в 0.
0
 Аватар для blbulyan
12 / 10 / 3
Регистрация: 31.10.2017
Сообщений: 126
26.08.2019, 12:07  [ТС]
Цитата Сообщение от j2FunOnly Посмотреть сообщение
Фон не белый, когда фон не установлен он имеет значения (0, 0, 0, 0) - последний 0 - это непрозрачность.
У вас напутано с интервалами, а при клике вы пытаетесь остановить интервал (для этого используйте clearInterval(), а не clearTimeout()), увеличить счетчик и запустить интервал, и в функции Start() у вас counter устанавливается в 0.
Я подправил, но в ImgData.data всё равно нули, даже тогда, когда я ткнул верно, то есть по фигуре, цвет которой отличается от чёрного, вот новый код:
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
var timerId = 0;
var counter = 0;
var interval = 200;
var MyCanvas = document.getElementById('mycanvas');
var c = MyCanvas.getContext('2d');
c.fillStyle = 'white';
function randomInteger(min, max) {
  return Math.floor(Math.random() * (max - min) ) + min;
}
function ShowRandomCircle(){
    Clear();
    let Radius = randomInteger(20, 50);
    let Colours = ['red', 'blue', 'green'];
    let CelectedColour = Colours[randomInteger(0, 3)];
    c.beginPath();
    c.fillStyle = Colours[randomInteger(0, 3)];
    switch(randomInteger(1, 4)){
        case 1:{//круг
            c.arc(randomInteger(Radius, MyCanvas.width+1 - Radius), randomInteger(Radius, MyCanvas.height+1 - Radius), Radius, 0, 2*Math.PI);
            c.stroke();
            c.fill();
            break;
        }
        case 2:{//квадрат
            let a = randomInteger(20, 50);
            c.fillRect(randomInteger(0, MyCanvas.width+1 - a), randomInteger(0, MyCanvas.height+1 - a), a, a);
            break;
        }
        case 3://треугольник
            let xybegin = [randomInteger(0, MyCanvas.width+1), randomInteger(0, MyCanvas.height+1)];
            let xy2 = [randomInteger(xybegin[0]+5, xybegin[0]+100), randomInteger(xybegin[1]+5, xybegin[1]+100)];
            c.moveTo(xybegin[0], xybegin[1]);
            c.lineTo(xy2[0], xy2[1]);
            c.lineTo(randomInteger(xy2[0]+5, xy2[0]+100), randomInteger(xy2[1]+5, xy2[1]+100));
            c.closePath();
            c.stroke();
            c.fill();
            break;
    }
    
}
function Start(){
    counter = 0;
    timerId = setInterval(ShowRandomCircle, document.getElementById('setinterval').value);
}
function ModifyInterval(){
    if(timerId != 0){
        Stop();
        interval = document.getElementById('setinterval').value;
        Start(interval);
    }
    
}
function Stop(){
    clearInterval(timerId);
    timerId = 0;
}
function Clear(){
    c.clearRect(0, 0, MyCanvas.width, MyCanvas.height);
}
function MouseClickEvent(event){
    Stop();
    let ImgData = c.getImageData(event.clientX, event.clientY, 1, 1);
    if(((ImgData.data[0] != 0xFF) || (ImgData.data[1] != 0xFF) || (ImgData.data[2] != 0xFF)) && (ImgData.data[3] > 0)){
        document.getElementById('counter').innerHTML = ++counter;
    }
    timerId = setInterval(ShowRandomCircle, interval);
}
Добавлено через 1 час 17 минут
Я ещё раз подправил код, теперь если ткнуть по фигуре то в пикселе содержится 255 255 255 255, но всё равно клик по фигуре не засчитывается:
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
var timerId = 0;
//var counter = 0;
var interval = 200;
var MyCanvas = document.getElementById('mycanvas');
var c = MyCanvas.getContext('2d');
function randomInteger(min, max) {
  return Math.floor(Math.random() * (max - min) ) + min;
}
function ShowRandomCircle(){
    Clear();
    let Radius = randomInteger(20, 50);
    let Colours = ['red', 'blue', 'green'];
    let CelectedColour = Colours[randomInteger(0, 3)];
    c.beginPath();
    c.fillStyle = Colours[randomInteger(0, 3)];
    switch(randomInteger(1, 4)){
        case 1:{//круг
            c.arc(randomInteger(Radius, MyCanvas.width+1 - Radius), randomInteger(Radius, MyCanvas.height+1 - Radius), Radius, 0, 2*Math.PI);
            c.stroke();
            c.fill();
            break;
        }
        case 2:{//квадрат
            let a = randomInteger(20, 50);
            c.fillRect(randomInteger(0, MyCanvas.width+1 - a), randomInteger(0, MyCanvas.height+1 - a), a, a);
            break;
        }
        case 3://треугольник
            let xybegin = [randomInteger(0, MyCanvas.width+1), randomInteger(0, MyCanvas.height+1)];
            let xy2 = [randomInteger(xybegin[0]+5, xybegin[0]+100), randomInteger(xybegin[1]+5, xybegin[1]+100)];
            c.moveTo(xybegin[0], xybegin[1]);
            c.lineTo(xy2[0], xy2[1]);
            c.lineTo(randomInteger(xy2[0]+5, xy2[0]+100), randomInteger(xy2[1]+5, xy2[1]+100));
            c.closePath();
            c.stroke();
            c.fill();
            break;
    }
    
}
function Start(){
    counter = 0;
    c.fillStyle = 'white';
    c.fillRect(0,0,MyCanvas.width,MyCanvas.height);
    timerId = setInterval(ShowRandomCircle, document.getElementById('setinterval').value);
}
function ModifyInterval(){
    if(timerId != 0){
        Stop();
        interval = document.getElementById('setinterval').value;
        Start(interval);
    }
    
}
function Stop(){
    clearInterval(timerId);
    timerId = 0;
}
function Clear(){
    c.fillStyle = 'white';
    c.fillRect(0,0,MyCanvas.width,MyCanvas.height);
}
function MouseClickEvent(event){
    Stop();
    let ImgData = c.getImageData(event.clientX, event.clientY, 1, 1);
    if(((ImgData.data[0] != 0xFF) || (ImgData.data[1] != 0xFF) || (ImgData.data[2] != 0xFF)) && (ImgData.data[3] > 0)){
        document.getElementById('counter').innerText = ++document.getElementById('counter').innerText;
    }
    timerId = setInterval(ShowRandomCircle, interval);
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
26.08.2019, 12:07
Помогаю со студенческими работами здесь

Получить цвет пикселя
Имеется указатель на массив битов, полученный, например, функцией GetDIBits. Собственно вопрос: как из этого массива получить RGB пикселя с...

Получить цвет пикселя
Всем привет. Как получить цвет пикселя в PictureBox?

Получить цвет пикселя в изображении
private void MainImage_OnMouseDown(object sender, MouseButtonEventArgs e) { ImageSource imageSource =...

QBitmap получить цвет пикселя
Какой метод в QBitmap возвращает цвет пикселя(x,y) или возможно существует другой класс, который сможет это сделать?

Как получить цвет пикселя?
Его координаты у меня есть


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&amp;d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru