Avatar billede d34c0n Praktikant
15. maj 2006 - 03:27 Der er 27 kommentarer og
1 løsning

Finde RGB farve på skærm

jeg mangler noget hjælp til at lave noget som scanner mit screen for at finde en bestemt farve værdi (rgb), og jeg kan og vil ikke bruge GetPixel(). det skal være noget lign. FindColor som SCAR programmet (meget hurtig!!) bruger hvis det er noget du kender..

jeg fik et tip om at jeg gemme mit screen til en buffer og søge den iigennem for farve værdien.. grunden til jeg ikke vil/kan bruge GetPixel er at den er alt alt for langsom og tager meget cpu ved at scanne hvert enkel pixel igennem på skærmen...

hjælp §§ :)
Avatar billede quiw Nybegynder
15. maj 2006 - 09:01 #1
Nu du siger Scar, så skulle det vel ikke være fordi du er ved at programmere et auto-hack til netstationen?
Avatar billede quiw Nybegynder
15. maj 2006 - 11:03 #2
- Men følger med i tråden anyway :)
Avatar billede bertelbrander Novice
15. maj 2006 - 17:35 #3
Hvis du downloader JDraw fra:
http://home20.inet.tele.dk/midgaard/sample.html#images
Du skal kun bruge image.cpp og image.h

Og indsætter denne linie i ImageClass i image.h:

  int32_t GetPixel(int32_t aY, int32_t aX) {return (GetAt(aY, aX, 0) << 16) + (GetAt(aY, aX, 1) << 8) + (GetAt(aY, aX, 2) << 0); }

Kan du lave noget i stil med:
#include <iostream>

#include <windows.h>
#include "imagewin.h"

static const unsigned int ColorToFind = RGB(0, 253, 0);

int main()
{
  ImageClass Image;
  if(!Image.CreateFromScreenDump())
  {
      std::cout << "Failed to create from screen dump" << std::endl;
      return 1;
  }
  std::cout << Image.GetWidth() << " * " << Image.GetHeight() << std::endl;
  int32_t X, Y;
  for(Y = 0; Y < Image.GetHeight(); Y++)
      for(X = 0; X < Image.GetWidth(); X++)
        if(Image.GetPixel(Y, X) == ColorToFind)
            std::cout << "Found at: " << X  << ", " << Y << std::endl;
}
Avatar billede d34c0n Praktikant
16. maj 2006 - 13:43 #4
du siger jeg kun skal bruge image.cpp og image.h men dog inkluderer du "imagewin.h" alligevel? nå men giver det lige et forsøg...

guiw -> hvad er netstationen? :D
Avatar billede d34c0n Praktikant
16. maj 2006 - 14:01 #5
GetRGB.obj : error LNK2001: unresolved external symbol "public: bool __thiscall ImageClass::CreateFromScreenDump(void)" (?CreateFromScreenDump@ImageClass@@QAE_NXZ)
Avatar billede d34c0n Praktikant
16. maj 2006 - 14:23 #6
og jeg har linket til ./jpeg-6b/jpeglibvc.lib
Avatar billede bertelbrander Novice
16. maj 2006 - 19:23 #7
Det er en fejl, det skulle være
#include "image.h"
Men imagewin.h inkluderer image.h, så det virker.

Det er ikke nødvendigt at linke med jpeg biblioteket (medmindre du vil bruge jpg funktioner), du skal derimod linke med image.cpp, sansynligvis ved at inkludere den i dit projekt.
Avatar billede d34c0n Praktikant
16. maj 2006 - 23:02 #8
det virker ikke. efter at have inkluderet image.cpp til mit projekt får jeg flere link errors.

image.obj : error LNK2001: unresolved external symbol "int __cdecl ReadJpegFile(char const *,unsigned int * * &,int &,int &,bool &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &)" (?ReadJpegFile@@YAHPBDAAPA
PAIAAH2AA_NAAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
image.obj : error LNK2001: unresolved external symbol "void __cdecl WriteJpegFile(char const *,unsigned int * * &,int &,int &,int)" (?WriteJpegFile@@YAXPBDAAPAPAIAAH2H@Z)
Debug/GetRGB.exe : fatal error LNK1120: 2 unresolved externals
Avatar billede bertelbrander Novice
16. maj 2006 - 23:05 #9
Ser ud til at du er nødt til at linke det hele med hvis du vil bruge VisualC++
Eller klip de dele af image.h ud som du ikke bruger.
Avatar billede bertelbrander Novice
16. maj 2006 - 23:15 #10
Du kan ændre de to prototyper i toppen af image.h til:

inline int ReadJpegFile(const char *aFilename, uint32_t **&aData, int32_t &aWidth, int32_t &aHeight, bool &IsMono, std::string &ErrorString)
{
  return 0;
}

inline void WriteJpegFile(const char *aFilename, uint32_t **&aData, int32_t &aWidth, int32_t &aHeight, int aQuality)
{
}

Så bør det virke
Avatar billede d34c0n Praktikant
16. maj 2006 - 23:21 #11
ok jeg fik den godt nok til at virke, men jeg kan ikke lige så hvordan den der metode skulle være bedre end en simpel loop med GetPixel?
Avatar billede bertelbrander Novice
16. maj 2006 - 23:23 #12
CreateFromScreenDump henter et helt skærm billede på én gang, det er meget hurtigere end at hente én pixel fra skærmen af gangen.

Jeg tror ikke det kan gøres meget hurtigere.
Avatar billede bertelbrander Novice
16. maj 2006 - 23:31 #13
Hvis det går for langsomt kan du kikke på koden for ImageClass::CreateFromScreenDump.

Delen til og med GetDIBits kan du ikke ændre så meget på, du kan måske allokere plads én gang for alle.

Delen med BmpMaskImageClass<uint32_t>::Read kan du godt undvære, hvis du er sikker på formatet af data på skærmen, og ved hvordan du skal læse i den rå buffer.
Avatar billede d34c0n Praktikant
16. maj 2006 - 23:32 #14
ja jeg kan godt se at den er hurtigere det er altid noget. men hvis nu jeg hele tiden skal søge efter den rgb farve så tager det jo lige så meget cpu forbrug. den ligger på over 90% forbrug. nogen ideer?

det jeg ikke forstår er hvordan programmet scar reagerer med det samme på en bestemt farve værdi og dog alligevel kan den stå og køre i baggrunden uden at bruge cpu forbrug?
Avatar billede bertelbrander Novice
16. maj 2006 - 23:36 #15
Den kan ikke stå og scanne skærmen for en bestemt farve konstant uden at den bruger CPU tid.

Du kan starte en timer som skanner ved timeout eller indsætte en sleep for hver runde.

Eller du kan starte en tråd med lav prioritet som gør arbejdet. Så generer den ikke så meget.
Avatar billede d34c0n Praktikant
16. maj 2006 - 23:39 #16
jamen hvis jeg fik en thread til at udføre koden ville det jo tage samme cpu forbrug?
Avatar billede bertelbrander Novice
16. maj 2006 - 23:40 #17
Ja, men hvis du sætter prioriteten ned, vil den kun køre når der ikke er vigtigere ting at lave.
Avatar billede d34c0n Praktikant
16. maj 2006 - 23:42 #18
ja okay har så ingen anelse om hvordan jeg sætter prioritet ned kan du gi nogn hints?
Avatar billede d34c0n Praktikant
16. maj 2006 - 23:48 #19
bertelbrander, vil jeg kunne bruge SetCursorPos med X og Y variablerne?
Avatar billede d34c0n Praktikant
16. maj 2006 - 23:52 #20
ser ikke ud til at virke med SetCursorPos den rykker hen til steder der ikke er rød (hvis RGB(255,0,0))
Avatar billede bertelbrander Novice
16. maj 2006 - 23:53 #21
Du kan se et simpelt eksempel på tråde her:
http://home20.inet.tele.dk/midgaard/snip/thread.html
Man sætter prioritet med SetThreadPriority.

Du kan godt bruge x og y med SetCursorPos, men Y vender omvendt i bit-maps, så du skal bruge noget i stil med

Image.GetHeight() - y
Avatar billede d34c0n Praktikant
16. maj 2006 - 23:56 #22
hvordan vender omvendt??
Avatar billede bertelbrander Novice
17. maj 2006 - 00:04 #23
Normalt er 0,0 det øverste venstre hjørne på skærmen.

Men med bitmaps er 0,0 det nederste venstre hjørne.
Avatar billede d34c0n Praktikant
17. maj 2006 - 00:07 #24
er det kun y der vender omvendt i bitmaps?
Avatar billede bertelbrander Novice
17. maj 2006 - 00:09 #25
Ja, det er kun Y
Avatar billede d34c0n Praktikant
17. maj 2006 - 00:11 #26
ok lav lige et svar så siger jeg tak :)
Avatar billede bertelbrander Novice
17. maj 2006 - 00:15 #27
Jeg samler ikke på point.
Avatar billede d34c0n Praktikant
17. maj 2006 - 00:16 #28
ok
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester