Узнать цвет пикселя

SSS

Пользователь
вопрос: как узнать цвет пикселя в окне своей программы на WinAPI или MFC?
 

SCTRWD

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

Функция GetPixel, имхо. Но слишком злоупотреблять ею не советую - работает ОЧЕНЬ медленно. А у меня было, что после несколько тысяч вызовов - просто переставала работать и выдавала неправильный результат :huh:

Я хранил отдельный Bitmap в памяти и с ним сверялся.
 

sami

Местный
рабочей области окна. просто я рисую в нем с помощью мышки линии и надо узнать в каких местах одна перекрывает другую.
Например, GetPixel методом.
Еще можно создать DIB секцию, и копировать на него с контекста окна BitBlt-ом. Но это "грязные" подходы, т.к. в разные моменты времени на окне может быть не совсем то, что там рисовалось, да и цвет пикселя может не совпасть с цветом ожидаемой линии хотя бы из-за несовпадения разрядности устройств.
Потому лучше "запоминать", что рисуется на окне в DIB секции.

А вообще, растровый анализ при рисовании векторных данных - не лучшая идея. Гораздо проще запоминать координаты нарисованных линий, чтобы находить их пересечения рассчетами, а не по цвету пикселя.
 

SCTRWD

Местный
Например, GetPixel методом.
Еще можно создать DIB секцию, и копировать на него с контекста окна BitBlt-ом. Но это "грязные" подходы, т.к. в разные моменты времени на окне может быть не совсем то, что там рисовалось, да и цвет пикселя может не совпасть с цветом ожидаемой линии хотя бы из-за несовпадения разрядности устройств.
Потому лучше "запоминать", что рисуется на окне в DIB секции.

А вообще, растровый анализ при рисовании векторных данных - не лучшая идея. Гораздо проще запоминать координаты нарисованных линий, чтобы находить их пересечения рассчетами, а не по цвету пикселя.

Вот когда векторных данных будет - туева хуча, находить их "пересечения рассчетами" станет слишком накладно для движения мышкой :huh: DIB секции - реальный выход. Хотя и памяти жрёт немеренно, особенно если надо различать разные типы нарисованного на экране, и для разных типов - по разному реагировать :p
 

SSS

Пользователь
Вот когда векторных данных будет - туева хуча, находить их "пересечения рассчетами" станет слишком накладно для движения мышкой :huh: DIB секции - реальный выход. Хотя и памяти жрёт немеренно, особенно если надо различать разные типы нарисованного на экране, и для разных типов - по разному реагировать :p
объясните нубу что есть DIB секции?
 

sami

Местный
Вот когда векторных данных будет - туева хуча, находить их "пересечения рассчетами" станет слишком накладно для движения мышкой :huh: DIB секции - реальный выход. Хотя и памяти жрёт немеренно, особенно если надо различать разные типы нарисованного на экране, и для разных типов - по разному реагировать :p
Две пересекающиеся растровые линии могут и "не пересечься". А когда линий много и они разных цветов, то будет очень сложно определить, пересеклись ли они, и вообще, где тут линии B)

Да, а когда будет хуча, можно будет прикрутить какое-нибудь индексирование отрезков на плоскости, чтобы не проверять пересечения со всеми.
 

SSS

Пользователь
Две пересекающиеся растровые линии могут и "не пересечься". А когда линий много и они разных цветов, то будет очень сложно определить, пересеклись ли они, и вообще, где тут линии :huh:


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

sami

Местный
в моем случае есть только черный и белый
даже для двух цветов определить факт пересечения линий в растре нетривиально.

Возьмем две диагональные линии. Они могут пересекаться не имея общих пикселов. Определить точку пересечения, имея координаты, гораздо проще.
 

SCTRWD

Местный
объясните нубу что есть DIB секции?

Дублируй то, что пользователь видит на экране в памяти. В черно-белом варианте. А при движении мышкой сверяйся с DIB секцией. Это гораздо быстрее и надёжнее чем с экрана считывать. Естественно надо позаботиться, чтобы DIB секция обновлялась соответсвенно :huh:

Две пересекающиеся растровые линии могут и "не пересечься". А когда линий много и они разных цветов, то будет очень сложно определить, пересеклись ли они, и вообще, где тут линии

Да, а когда будет хуча, можно будет прикрутить какое-нибудь индексирование отрезков на плоскости, чтобы не проверять пересечения со всеми.

Не пересекутся - забота пользователя, пусть меняет масштаб и перерисовывает изображение. А как эффективно прикрутить индексирование к функциям GDI, которые формируют изображение на экране - я лично не знаю. Такой подход просто бесполезен для изображений, где все линии имеют более менее одинаковые габариты.
 

SCTRWD

Местный
даже для двух цветов определить факт пересечения линий в растре нетривиально.

Возьмем две диагональные линии. Они могут пересекаться не имея общих пикселов. Определить точку пересечения, имея координаты, гораздо проще.

Правильно. Для этого в DIB секции рисуют достаточно "толстые" линии. А если нужно ловить именно точки пересечения, то можно организовать для них отдельную DIB секцию :huh:
 

sami

Местный
Не пересекутся - забота пользователя, пусть меняет масштаб и перерисовывает изображение. А как эффективно прикрутить индексирование к функциям GDI, которые формируют изображение на экране - я лично не знаю. Такой подход просто бесполезен для изображений, где все линии имеют более менее одинаковые габариты.
Прикрутить индексирование к GDI? такой цели нет. Можно просто хранить координаты. Но если нужно - можно вставить абстракцию между GDI и кодом, который на него отправляет линии.

По части эффективности индексаци: зависит от способа индексации. Могут иметь значения не габариты, а bounding-box-ы линий. Так при одинаковых габаритах в 1/10 часть окна эффективность индексации может быть велика. При 1/2 окна не так велика. При 9/10 окна - малоэффективна. Ну там можно придумать какой-нибудь другой индекс.

Правильно. Для этого в DIB секции рисуют достаточно "толстые" линии. А если нужно ловить именно точки пересечения, то можно организовать для них отдельную DIB секцию :huh:
Вдруг надо определить координату пересечения с точностью до пиксела? Или долей пиксела?

Да, можно организовать ОЧЕНЬ широкую отдельную DIB секцию, но ходить по ней может быть заметно дороже, чем по массиву координат линий.
 

SCTRWD

Местный
Вдруг надо определить координату пересечения с точностью до пиксела? Или долей пиксела?

Да, можно организовать ОЧЕНЬ широкую отдельную DIB секцию, но ходить по ней может быть заметно дороже, чем по массиву координат линий.

Так всё-таки пиксель или реальная точка пересечения в реальных координатах? Тогда это другая задача. И думаетцо, серьёзные приложения типа AutoCAD или Illustrator со Smart Guides комбинируют эти подходы. Или занимаются предварительным счётом в фоновом режиме :huh:

bounding-box - это и есть габариты в моём понимании, звиняюсь, что не решился употребить этот английский вариант :p

Просто чо хочу сказать B) Ходить по координатам и вычислять при движении мышки - тупиковый подход.
 

SSS

Пользователь
....................

Да, можно организовать ОЧЕНЬ широкую отдельную DIB секцию, но ходить по ней может быть заметно дороже, чем по массиву координат линий.
массив координат линий есть, но думаю что выделить прямоугольник из DIB с координатами от начала до конца вектора и искать в нем пересечения проще
 

SCTRWD

Местный
Прикрутить индексирование к GDI? такой цели нет. Можно просто хранить координаты. Но если нужно - можно вставить абстракцию между GDI и кодом, который на него отправляет линии.

А "абстракция" Вам скажет, где и как прошла линия? Где и как она растеризировалась? В каком пикселе она есть, а в каком её нет?
 

sami

Местный
Так всё-таки пиксель или реальная точка пересечения в реальных координатах? Тогда это другая задача. И думаетцо, серьёзные приложения типа AutoCAD или Illustrator со Smart Guides комбинируют эти подходы. Или занимаются предварительным счётом в фоновом режиме :huh:
Как считаете, сколько миллионов пересечений линий можно проверить за десятую долю секунды?

bounding-box - это и есть габариты в моём понимании, звиняюсь, что не решился употребить этот английский вариант :p
Конечно, если все линии напихать в один bounding-box, то толку от индекса будет немного. Но он не предназначен для работы в крайних случаях.

Просто чо хочу сказать B) Ходить по координатам и вычислять при движении мышки - тупиковый подход.
Просто хочу сказать, что я занимался ГИС-системами, как промышленными, так и с уровнем предприятия. Для того, чтобы ощутить заметные тормоза от мышки при попытке вычислить пересечения с примитивами, нужно их иметь такое немыслимое кол-во на экране, что в глазах будет рябить. А мелкие невидимые глазу линии, да и более крупные, но находящиеся далеко от окна просмотра, легко отбрасываются индексом.

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

А "абстракция" Вам скажет, где и как прошла линия? Где и как она растеризировалась? В каком пикселе она есть, а в каком её нет?
скажет, если абстракция будет владеть алгоритмами растровой развертки.
Причем, она даже сможет сказать какие именно линии проходят через конкретный пиксел.
 

SCTRWD

Местный
Как считаете, сколько миллионов пересечений линий можно проверить за десятую долю секунды?

Очень много, особенно если линии - эллипсы. Уравнения четвёртого порядка - это не баран чихнул :p

Конечно, если все линии напихать в один bounding-box, то толку от индекса будет немного. Но он не предназначен для работы в крайних случаях.

А знаете как часто это бывает?

Просто хочу сказать, что я занимался ГИС-системами, как промышленными, так и с уровнем предприятия. Для того, чтобы ощутить заметные тормоза от мышки при попытке вычислить пересечения с примитивами, нужно их иметь такое немыслимое кол-во на экране, что в глазах будет рябить. А мелкие невидимые глазу линии, да и более крупные, но находящиеся далеко от окна просмотра, легко отбрасываются индексом.

Везёт Вам - ГИС-системы - песня B)

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


А Вы владеете алгоритмами? Знаете, как Microsoft сегодня решил реализовать развертку?

"Причем, она даже сможет сказать...", но считать придётся много, для любого пикселя. Придётся заново пересчитывать. Либо опять же пользоваться GetPixel - со всеми вытекающими :huh:
 

sami

Местный
Очень много, особенно если линии - эллипсы. Уравнения четвёртого порядка - это не баран чихнул B)
Полагаю, что Вы хотели сказать "не очень много".

А знаете как часто это бывает?
безотносительно условий задачи затрудняюсь ответить.

Везёт Вам - ГИС-системы - песня :)
Начальство наступило этой песне на горло.

А Вы владеете алгоритмами? Знаете, как Microsoft сегодня решил реализовать развертку?
Там где нет антиалиасинга все довольно просто. Эмулируется и подгоняется за пару вечеров с высокой вероятностью совпадения результата. Но с нововведениями и уходом от GDI становится сложнее. Впрочем и анализировать растр с целью найти пересечения линий с антиалиасингом - тоже не быстро. :p

"Причем, она даже сможет сказать...", но считать придётся много, для любого пикселя. Придётся заново пересчитывать. Либо опять же пользоваться GetPixel - со всеми вытекающими :huh:
не понял, почему придется много считать для любого пикселя? Можно хранить списки линий для каждого пикселя... Можно хранить не списки, а идентификаторы списков, чтобы можно было расшаривать списки линий для разных пикселей. Своя абстракция может работать с любой структурой данных (хоть с ленивой разреженной матрицей), а не только DIB секций.
 

SCTRWD

Местный
Полагаю, что Вы хотели сказать "не очень много".

Да както хотел сказать именно много :p По моему, у всех точных алгоритмов эллипсы - больное место.

безотносительно условий задачи затрудняюсь ответить.

Вот привести реальную постановку задачи гриф не позволяет. Но поверьте наслово - это очень большой пласт задач B)


Начальство наступило этой песне на горло.

Сочуствую :)

Там где нет антиалиасинга все довольно просто. Эмулируется и подгоняется за пару вечеров с высокой вероятностью совпадения результата. Но с нововведениями и уходом от GDI становится сложнее. Впрочем и анализировать растр с целью найти пересечения линий с антиалиасингом - тоже не быстро. :huh:

И я о том же: это не быстро, не надёжно и писями по воде виляно :D

не понял, почему придется много считать для любого пикселя? Можно хранить списки линий для каждого пикселя... Можно хранить не списки, а идентификаторы списков, чтобы можно было расшаривать списки линий для разных пикселей. Своя абстракция может работать с любой структурой данных (хоть с ленивой разреженной матрицей), а не только DIB секций.

Для каждого пикселя хранить списки? "расшаривать списки линий для разных пикселей"? Вы - серьёзно?

Походу, вообще о разных вещах говорим :D Из разных категорий применения. У меня - чертежи в десятки тысяч линий с коэффициентом разномасштабности - 1:100, а у Вас?
 
Сверху