Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Delphi: Для новичков > Инвертировать часть изображения |
Автор: PsiMagistr 23.6.2010, 09:44 |
Ребята, мне надо инвертировать часть изображения. Какие есть пути решения пограмотней? |
Автор: DarkProg 23.6.2010, 09:53 |
Если просто прямоугольником от координаты (x1, y1) до (x2, y2), то можно скопировать часть изображения на отдельный битмап, и там уже его инвертировать, а решений есть много одно из них вы с легкостью найдёте в DRKB или Delphiworld |
Автор: PsiMagistr 23.6.2010, 10:17 |
Спасибо. Это на поверхности конечно. А без создания отдельного BitMap? |
Автор: AntonN 23.6.2010, 11:46 |
пробегаешь по канвасу (если оно есть) или по пикселям битмапа (если он есть) сканлайном, достаешь каналы пикселя (GetRvalue() например, у сканлайна они уже готовые), отнимаешь их от 255 и записываешь обратно |
Автор: Snowy 23.6.2010, 12:19 | ||
Зачем сканлайн? Это долго. Да и смысл изобретать велосипед, когда всё уже готово. И да, можно без второго битмапа. И всего в одну строку. Допустим, нужно инвертировать прямоугольную область x100:y50, шириной 200:100
|
Автор: Frees 23.6.2010, 12:35 | ||
|
Автор: PsiMagistr 23.6.2010, 12:42 | ||
Спасибо. Но пока не вышло. Имею Image на форме. При нажатии на кнопку должен инвертироваться прямоугольник. Координаты верхней точки прямоугольника 0, 0. ширина 128, высота 83. Пробовал
Ноль внимания. Добавлено через 1 минуту и 9 секунд Frees, спасибо, сейчас еще ваш пример попробую. Добавлено через 6 минут и 26 секунд Frees, Ваше работает однако. А что за метод: CopyMode? И что такое cmSrcCopy; |
Автор: Snowy 23.6.2010, 12:58 | ||
Правильно. Код только инвертирует изображение. Но не рисует его. В случае с имаджем, нужно его обновить.
CopyMode - последний параметр в BitBlt. cmDstInvert в CopyRect - то же самое, что и DSTINVERT в BitBlt. |
Автор: PsiMagistr 23.6.2010, 13:28 |
Snowy, Сенкс, воспользовался BitBlit. |
Автор: AntonN 23.6.2010, 14:03 | ||
Snowy,
долго для чего? |
Автор: PsiMagistr 23.6.2010, 14:34 |
AntonN, Если сканлайнить то надо строки изображения циклом проходить, как я понял... |
Автор: PsiMagistr 23.6.2010, 16:30 | ||||
Заметил любопытнейшую вещь. Если ДО вызова функции BitBlt выполнить в Image загрузку изображения из какого либо файла, действие функции отображается несмотря на отсутствие refresh. То есть
Визуально аналогично следующему:
Как и почему так получается не разобрался. Да картинка вроде обновляется из за загрузки. Но она же обновляется до операции BitBlt |
Автор: Mikel 23.6.2010, 16:49 |
Скорее всего оно перерисовывается сообщением, которое обрабатывается после того как исполнится весь код и будет выполняться обработчик сообщений. |
Автор: PsiMagistr 23.6.2010, 17:08 | ||
Mikel, Шут его знает дружище, вот например погляди:
|
Автор: PsiMagistr 24.6.2010, 08:40 | ||
Просто пытаюсь понятькак работает функция. Все интересней и интересней. Есть два Image. ImgMap, ImLocation. В ImgLocation есть некое стартовое изображение по умолчанию. Мы берем ImMap, и копируем оттуда кусочек в ImgLocation. Копировать надо с инвертированием. Итак:
|
Автор: Mikel 24.6.2010, 08:50 |
Ну да, скорее всего если вместо ImgLocation.Canvas.CopyRect(R1, ImgMap.Canvas, R2); будешь работать не с канвами самого image, а с bitmap.canvas, то не перерисуется ![]() Работает- оставь и не трогай ![]() |
Автор: PsiMagistr 24.6.2010, 08:53 |
Гм. Ничего не понял. Как инверт-режим может мешать правильному копированию участка? |
Автор: PsiMagistr 24.6.2010, 09:21 |
Не поленюсь - выложу исходный кусок. |
Автор: PsiMagistr 24.6.2010, 10:38 | ||||
Как будто точно от режима зависит. странно. При попытке просто копировать участок изображения в другой Image
Как по маслу. При попытке изменить режим на DstInvert, чтобы :
Не происходит копирования участка. |
Автор: AntonN 24.6.2010, 11:27 | ||
|
Автор: PsiMagistr 24.6.2010, 11:33 |
Спасибо большое. Только долго. |
Автор: AntonN 24.6.2010, 11:54 | ||||
PsiMagistr,
Долго? для чего долго? Добавлено через 2 минуты и 11 секунд 1000 инвертирований за 0,6 секунды областей 250*250 - это долго? Добавлено через 5 минут и 7 секунд небольшое изменение...
и те же 1000 инвертов улетают за 0,18 секунды, это 5555 операций в секунду? ты ничего с "долго" не перепутал? |
Автор: PsiMagistr 24.6.2010, 12:15 |
Не перепутал дружище. Если есть функция инвертирования, то зачем изобретение велосипеда?) |
Автор: AntonN 24.6.2010, 12:15 | ||
сканлайн оказался быстрее на 20% (глубина цветности дисплея 32 бита). "Долго"... Это еще без оптимизации до асма, пара xor+add с такой скоростью улетят, что моргнуть не успеем... |
Автор: AntonN 24.6.2010, 12:15 |
PsiMagistr, я и вжу как она есть, уже второй день не можешь ее победить ![]() а потом вдруг тебе понадобится серпия, crayscale, еще что нибудь - тоже готовое будешь искать? ![]() |
Автор: Mikel 24.6.2010, 12:32 | ||
Я не понял что ты хочешь, но попробуй так: )))
|
Автор: AntonN 24.6.2010, 12:34 | ||
С позволения, я еще пофлужу...
накидал на скорую руку, выполняется при тех же параметрах из моего предшествующего поста за 0.3 секунды, это чуть больше чем в 2.5 раза быстрее BitBlt() хотя вероятно где-то есть корявки, удивлен что BitBlt() в этом режиме показывает такие низкие результаты... |
Автор: Snowy 24.6.2010, 13:14 |
Для точности эксперимента увеличил до 10000 инверсий. Результат на моем ноуте: InvertRect_GDI - 40 секунд BitBlt - 13 секунд Итог: Битблит в 3 раза быстрее |
Автор: AntonN 24.6.2010, 13:21 |
У меня просто проц не слабый. С последней функцией можешь сравнить? просто интересно |
Автор: PsiMagistr 24.6.2010, 13:23 |
Спасибо большое. Уже ассемблерные вставки появились. ![]() |
Автор: PsiMagistr 24.6.2010, 13:58 |
Ребята, все. Уф-ф-ф. Спасибо всем. Причина: У меня картинка не очень чистая была. На глаз нипочем не заметно. А при инвертировании - пятна моментом. Добавлено через 2 минуты и 39 секунд Ребята, все. Уф-ф-ф. Спасибо всем. Причина: У меня картинка не очень чистая была. На глаз нипочем не заметно. А при инвертировании - пятна моментом. |