Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[C++] pobieranie koloru piksela

mongoł2000 31 Paź 2009 18:37 5333 8
  • #1 31 Paź 2009 18:37
    mongoł2000
    Poziom 18  

    Witam! Poszukuje kodu źródłowego lub porad jak pobrać z ekranu kolor piksela. Bez problemów napisałem to za pomocą funkcji GetPixel ale szybkość jej działania nie jest zadowalająca :-/ ...szukając informacji w sieci napotknełem się na funkcje GetDIBits , jednak nie potrafiłem za jej pomocą wyciągnąć kolory z piksela w formacie COLORREF.

    0 8
  • #3 31 Paź 2009 19:57
    mongoł2000
    Poziom 18  

    tak, masz rację, pobieram co np dziesiąty piksel ekranu. Przy rozdzielczości 1300 na 740 trwa to ponad minutę:/...używam tego aby wyliczyć jaki jest przeważający kolor na ekranie...na jednym z forum wyczytałem że GetDIBits jest szybsza ale nie wiem jak doprowadzić ja do postaci która mi odda kolor pojedynczego piksela.

    0
  • #4 31 Paź 2009 20:09
    Dżyszla
    Poziom 42  

    Przy założeniu pobierania co 10 piksela raczej nie przyspieszysz. Jeśli zaś chcesz pobrać wszystkie lub przynajmniej większość, to proponuję wykonać najpierw kopię ekranu do pamięci i na niej operować. Przy okazji - pokaż obecny kod, może coś da się zoptymalizować...

    0
  • #5 31 Paź 2009 22:57
    mongoł2000
    Poziom 18  

    Code:
       hPulpit=GetDC(0);        
    
        hdc=BeginPaint(hwnd,&ps);
       
       for(x=0;x<=dwWidth;x+=10)
       {
       for(y=0;y<=(dwHeight/3);y+=10)
       {
             
          color= GetPixel(hPulpit,x,y);
          b=GetBValue(color);
          r=GetRValue(color);      
          g=GetGValue(color);
          a=(a+r)/2;
          d=(d+g)/2;
          c=(c+b)/2;
          color=RGB(a,d,c);
       
       }}

    ...z tą kopią obrazu też nie za bardzo bo wyświetlanie uśrednionego koloru ma być aktualizowane jak najczęściej, a to zajmie i tam więcej czasu a i tak nie ominie mnie wykorzystanie GetPixel.
    ...Wpadł mi pomysł z Bitmapami, otóż potrafię napisać program do screenshotów(właśnie korzystając z GetDIBits z którego nie wiem jak wyciągnąć kolory) , więc może jakaś funkcja pobierająca kolory pikseli bitmapy jest szybsza od GetPixel?

    0
  • #6 31 Paź 2009 23:26
    Dżyszla
    Poziom 42  

    Po pierwsze to to nie jest uśrednianie, chyba, że ostatni piksel ma największe znaczenie. Zrobiłeś średnią wagową z wagą rosnącą zgodnie z ciągiem x(n)*2.

    Po drugie to ja rozumiem, że wynikowa zmienna color jest jeszcze dalej przetwarzana?

    Czemu do 1/3 wysokości? A jeśli już konieczne, to wylicz tą wartość jeszcze przed pętlami - w przeciwnym wypadku będzie dzielenie przy każdym przebiegu.

    Po czwarte - po co to BeginPaint? Nic nie zapisujesz na obszarze.

    Zrobiłem GetPixel co 10 pixel w pionie i poziomie w Delphi - ekran o rozdzielczości 1680x1050 jest skanowany w ok 30-40ms... Tak więc coś masz ewidentnie nie tak z programem. Dołożenie Twojego algorytmu liczenia nie zmienia tego czasu zauważalnie o więcej niż 10ms)

    0
  • #7 01 Lis 2009 11:00
    mongoł2000
    Poziom 18  

    Wkradł się mały błąd, na końcu ma być inna zmienna , a nie color,
    BeginPaint zapomniałem usunąć, ale w całości programu jest potrzebny ponieważ później rysuje prostokąt o obliczonym średnim kolorze, a samo uśrednianię zdaje mi się dobre , poza tym że pierwsza wartość jest niepotrzebnie dzielona przez 2, ale dalej jest już ok i ten pierwszy pixel nie robi wielkiej różnicy.
    Może powiem do czego ta aplikacja ma być stworzona...
    ma to być coś na podobieństwo Ambilight tyle że pod pc.Program ma obliczać średnią kolorów z góry i boków ekranu(dlatego ta wysokość podzielona przez 3), a potem wysyłać do mikroprocesora komendy sterujące diodami.Dodatkowo w oknie aplikacji ma być na żywo podgląd wyświetlanych kolorów dlatego rysuje prostokąty na krawędziach okna.
    Spróbowałem napisać sama funkcję uśrednianic pod konsole, to czas pracy był podobny do czasu pracy pod WinApi.

    0
  • #8 01 Lis 2009 13:05
    Dżyszla
    Poziom 42  

    Czy wg Ciebie
    (((x1+x2)/2+x3)/2+...+xn)/2=(x1+x2+...+xn)/n ? No wybacz, ale to jest wiedza na poziomie gimnazjum, jak nie wcześniej...

    BeginPaint stosujesz w momencie, gdy chcesz rysować i w Twoim interesie jest, by zablokowanie ekranu trwało jak najkrócej! Nie blokuj go więc wówczas, gdy to nie jest konieczne!

    Nie bardzo rozumiem ostatni zdanie - znaczy się wyeliminowałeś GetPixel i dalej czas był tak samo długi? To chyba miałbyś odpowiedź, co tak naprawdę jest problemem.

    0
  • #9 02 Lis 2009 18:34
    mongoł2000
    Poziom 18  

    wiem że to nie to samo, ale właśnie tak ma być że piksele bliżej krawędzi maja miec wiekszą wagę niż te bliżej środka, bo ledy w ambilight mają kolor taki jaki jest na krawędziach.
    W ostatnim zdaniu chodziło mi że napisałem tą funkcje pod konsole, bez tworzenia okna przycisków itp, tylko wyswietlało mi wartości pikseli,i także dziłało dośc długo.
    Może żeby udowodnić Tobie że GetPixel się nie nadaje zapodam kod który robi zrzut ekranu o rozdzielczości okna i wyświetla go w nim. Wszystko kompiluje się pod Visuala.
    proszę:

    Code:


    //

    #include "stdafx.h"

    #include "stdafx.h"
    #include <commctrl.h>
    #include<windows.h>
    #define IDC_BUTTON 1000
    #define IDC_LABEL1 1001
    #define IDC_LABEL2 1002
    #define IDC_LABEL3 1003
    #define IDC_LABEL5 1005

    int iIndex,x,y;
    HWND hEdit,hButton,hWnd,hEdit2, hCombo;
    int pack;
    int dwHeight;
    int dwWidth;
    CHAR szClassName[]="OknoRodzica";
    HINSTANCE* hInst;
    HBRUSH hbr,hbrd;
    COLORREF color,suma;
    LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
    DWORD doBitmap(HWND hwnd);
    HDC hPulpit;
    int r,g,b;
    HDC hdc,hDc;

    INT WINAPI WinMain(HINSTANCE hInstance,HINSTANCE,LPSTR lStart,INT nShow)
    {
      hInst=&hInstance;
      WNDCLASSEX wc;
      wc.hInstance=*hInst;
      wc.lpszClassName=szClassName;
      wc.lpfnWndProc=WndProc;
      wc.style=0;
      wc.cbSize=sizeof(WNDCLASSEX);
      wc.hIcon=LoadIcon(0,IDI_APPLICATION);
      wc.hIconSm=LoadIcon(0,IDI_APPLICATION);
      wc.hCursor=LoadCursor(0,IDC_ARROW);
      wc.lpszMenuName=0;
      wc.cbClsExtra=0;
      wc.cbWndExtra=0;
      wc.hbrBackground=0;
      if(!RegisterClassEx(&wc))  return 0;
      hWnd=CreateWindowEx(0,szClassName,"Ambilite PC 1.0",WS_MINIMIZEBOX|WS_SYSMENU|WS_EX_CONTROLPARENT,20,20,600,300,0,0,*hInst,0);
      ShowWindow(hWnd,nShow);
      MSG msgs;
      while(GetMessage(&msgs,0,0,0))
      {
        TranslateMessage(&msgs);
        DispatchMessage(&msgs);
      }
      return msgs.wParam;
    }

    LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wPar,LPARAM lPar)
    {
    int a=0,d=0,c=0;
      switch(msg)
      {
        case WM_CREATE:
       

    dwWidth=GetSystemMetrics(SM_CXSCREEN);
    dwHeight=GetSystemMetrics(SM_CYSCREEN);

          

       break;
       case WM_COMMAND:   
           break;
         case WM_PAINT:
          
       hPulpit=GetDC(0);       
      hdc=GetDC(hwnd);
       for(x=0;x<=600;x+=1)
       {
       for(y=0;y<=(300);y+=1)
    {
             
             color= GetPixel(hPulpit,x,y);
          b=GetBValue(color);   
          r=GetRValue(color);      
    //   
          g=GetGValue(color);
          a=(a+r)/2;
       d=(d+g)/2;
          c=(c+b)/2;
          suma=RGB(a,d,c);
       SetPixel(hdc,x,y,suma);
       }}
       DeleteObject(hPulpit);

          
       
          break;
        case WM_DESTROY:
     
        DeleteObject(hEdit2);
       DestroyWindow(hEdit);
       DestroyWindow(hButton);
       PostQuitMessage(0);
          break;
        default:
          return DefWindowProc(hwnd,msg,wPar,lPar);
      }

      return 0;
    }

     

    0