Филтър за показване C#

Малко е трудно да обясня какво ми трябва, но ще опитам:

Трябва да напиша приложение (winform), което ще бъде някакъв вид филтър за изображение/други форми зад него. С едно изключение - цялата форма отзад трябва да изглежда както е, с изключение на червения (например) цвят, който трябва да бъде заменен с всеки друг определен цвят, бял например.

Така че нека си представим, че съм отворил Windows Word с няколко реда текст. С червени и черни букви. Така че, когато поставя приложението си над този текст - то трябва да "филтрира" червените символи и да ги запълни до бяло.

И така, доколкото разбирам тази задача: трябва да щракна област зад формуляра, след това да го обработя (да заменя цветовете) и след това да начертая това изображение върху тялото на моя формуляр.

Някакви връзки или ключови думи за решение?

UPD:

така че - това е окончателното ми решение:

  1. направете форма прозрачна (използвайки свойствата TransparencyKey и BackColor)
  2. поставете картинна кутия върху формата
  3. когато трябва да актуализираме изображението в picturebox - заместваме текущото изображение с pictureBox1.Image = null;, след това опресняваме формата с (this.Refresh()) и правим нова моментна снимка

Благодаря за всичко ;-)

UPD 2: http://dl.dropbox.com/u/4486681/result.png

UPD 3: ето източници


person zerkms    schedule 02.03.2010    source източник
comment
+1 - Мисля, че това е страхотен въпрос.   -  person Kyle Rosendo    schedule 02.03.2010
comment
Трябва ли да е winforms? Подозирам, че подобни неща може да са по-лесни в WPF.   -  person Gabe    schedule 02.03.2010
comment
без ограничения или задължителни. това трябва да е Windows .net приложение с всякакъв вид форма (поне с надпис и бутон за затваряне) ;-)   -  person zerkms    schedule 02.03.2010


Отговори (2)


можете да създадете моментна снимка на работния плот, като използвате следния код:

public Bitmap CaptureScreen()
{
    Bitmap b = new Bitmap(SystemInformation.VirtualScreen.Width, SystemInformation.VirtualScreen.Height);
    Graphics g = Graphics.FromImage(b);
    g.CopyFromScreen(0, 0, 0, 0, b.Size);
    g.Dispose();
    return b;
}

Заменете размерите и позицията с координатите на вашата форма. По този начин получавате растерна карта на това, което стои зад вашата форма. След това можете да направите замяната на цвета на това растерно изображение.

Моля, имайте предвид, че поради настройки като ClearType и други механизми за антиалиасинг, трябва да вземете под внимание и "междинните пиксели", когато извършвате подмяната на цвета. Иначе нещата ще изглеждат смешни :-)

person Thorsten Dittmar    schedule 02.03.2010
comment
да, вече се сетих за близки цветове. това би било следващо предизвикателство ;-) така че - може ли някой да предложи по-добро решение? - person zerkms; 02.03.2010
comment
Страхотен ! Не знаех метода CopyFromScreen, точно защо си мислех, че @zerkms трябва да прибегне до C++ - person Timores; 02.03.2010

Не знам дали това изобщо може да се направи (да видим другите какво ще отговорят :-).

Можете да се справите с контекста на екранното устройство, което ви дава растерно изображение на екрана.

HDC dc = GetDC(NULL);

(Това е C++, ще трябва да използвате P/Invoke или да създадете библиотека със смесен режим в C++)

След това можете да преначертаете област от екрана с вашия процес на филтриране.

Сега започват проблемите:

  • откъде знаеш, че пикселите в твоя интересен регион са се променили?
  • ако регионът се промени, видими ли са промените или са скрити от собствената ви рисунка.

Може да имате бутон някъде, който скрива вашето собствено приложение за момент и го показва обратно при повторно натискане и филтрира новото съдържание.

Късмет. Има ли възможност за споделяне на потребителския сценарий?

person Timores    schedule 02.03.2010
comment
в моя случай - пикселите зад приложението ще бъдат статични, това ще опрости моето решение. (надявам се, че мога да направя това %), така че radrawing ще е необходим само в един случай: приложението ми е преместено или приложението ми връща фокуса, след като го е загубило. - person zerkms; 02.03.2010
comment
Това е добро опростяване. Мисля, че решението на @Thorsten е по-добро (без C++). - person Timores; 02.03.2010