Autor Beitrag
hathor
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 22.10.10 21:26 
Das ideale Pixelformat für die Bearbeitung mit ScanLine ist 24Bit, deshalb d.PixelFormat:= pf24Bit;
elundril
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3747
Erhaltene Danke: 123

Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
BeitragVerfasst: Fr 22.10.10 21:51 
Müsst man halt eine gute Balance finden. Warum sollt ich auf Scanline optimieren wenn BitBlt viel mehr Laufzeit verbraucht? Da schau ich doch das ich BitBlt schneller läuft und das scanline nicht so viel dazubekommt.

lg elundril

//Edit: hab zwar nicht das komplette Topic durchgelesen aber hier mal die DirectX-Variante: www.delphipraxis.net...hot-mit-directx.html

_________________
This Signature-Space is intentionally left blank.
Bei Beschwerden, bitte den Beschwerdebutton (gekennzeichnet mit PN) verwenden.
shana-chan Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17



BeitragVerfasst: Sa 23.10.10 01:12 
user profile iconhathor hat folgendes geschrieben Zum zitierten Posting springen:
Das ideale Pixelformat für die Bearbeitung mit ScanLine ist 24Bit, deshalb d.PixelFormat:= pf24Bit;

Hab garnicht gesehen das es schon eine 2te Seite gibt. War grade selbst drauf gekommen .. hat aber leider nur wenig gebracht.

Auserdem verwende ich jetzt "GetForeGroundWindow" statt "GetDesktopWindow" damit holt der sich nur das ausgewählte Fenster ist aber auch bei einem Video in Vollbild deutlich schneller. (10-20ms) EDIT: Nachteil ist, dass man abundzu Felermeldungen bekommt. ("Ungültiges Handle" und "Division durch Null") EDIT2: korrigiert.. scheint so besser zu gehen. EDIT3: Doch nicht besser. EDIT4: und die meldung "Scanline out of range".

Neuer Code:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Serial, ExtCtrls, ComCtrls, Grids, ValEdit;

type
  TForm1 = class(TForm)
    ser: TSerial;
    conf: TMemo;
    Timer1: TTimer;
    Panel1: TPanel;
    Panel2: TPanel;
    Panel3: TPanel;
    adjr: TTrackBar;
    adjg: TTrackBar;
    adjb: TTrackBar;
    Label1: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;  
  dat:array[0..6of byte;
  matrix:integer;

implementation

{$R *.dfm}

function ScreenColor(): TColor;
var
  s: pByteArray;
  d: TBitMap;
  DC: hdc;     
  Rec: TRect;
  r,g,b:int64;
  p,x,y,z:integer;    
  q1,q2,f:Int64;
begin            
  QueryPerformanceFrequency(f);
  try GetWindowRect(GetForeGroundWindow, Rec);
  finally
    d := TBitMap.Create;
    d.PixelFormat:=pf24Bit;
    d.Width  := Rec.Right - Rec.Left;
    d.Height := Rec.Bottom - Rec.Top;
    DC := GetWindowDC(GetForeGroundWindow);
    QueryPerformanceCounter(q1);
    BitBlt(d.Canvas.Handle, 00, d.Width, d.Height, DC, 00, SRCCOPY) ;
    QueryPerformanceCounter(q2);
    Form1.Label1.Caption:='ms for BilBlt: '+inttostr((q2-q1)*1000 div f);
    r:=0;
    g:=0;
    b:=0;
    for y:=0 to (d.Height-1div matrix do
      begin
        s:=d.ScanLine[y*matrix];
        for x:=0 to (d.Width-1div matrix do
          begin
            r:=r+s[x*matrix*3+2];
            g:=g+s[x*matrix*3+1];
            b:=b+s[x*matrix*3+0];
          end;
        end;
    ReleaseDC(0, DC);
    z:=((d.Height-1div matrix)*((d.Width-1div matrix);
    d.Free;
    r:=r div z;
    g:=g div z;
    b:=b div z;
    if r>250 then r:=250;
    if g>250 then g:=250;
    if b>250 then b:=250;
    result:=RGB(r,g,b);
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
conf.Lines.LoadFromFile('config.ini');
adjr.Position:=StrToInt(conf.Lines[10]);
adjg.Position:=StrToInt(conf.Lines[11]);
adjb.Position:=StrToInt(conf.Lines[12]);
matrix:=StrToInt(conf.Lines[7]);
Timer1.Interval:=StrToInt(conf.Lines[4]);
ser.COMPort:=StrToInt(conf.Lines[1]);
ser.OpenComm;
Timer1.Enabled:=True;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
conf.Lines[10]:=IntToStr(adjr.Position);
conf.Lines[11]:=IntToStr(adjg.Position);
conf.Lines[12]:=IntToStr(adjb.Position);
conf.Lines[7]:=IntToStr(matrix);
conf.Lines[4]:=IntToStr(Timer1.Interval);
conf.Lines[1]:=IntToStr(ser.COMPort);
conf.Lines.SaveToFile('config.ini');
ser.CloseComm;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  clr: TColor;
begin
  clr:=ScreenColor();
  color:=clr;
  dat[0]:=byte(255);
  dat[1]:=GetRValue(clr) * adjr.Position div 100;
  dat[2]:=GetGValue(clr) * adjg.Position div 100;
  dat[3]:=GetBValue(clr) * adjb.Position div 100;
  dat[4]:=dat[1];
  dat[5]:=dat[2];
  dat[6]:=dat[3];
  ser.TransmittData(dat,7);
end;

end.


Zuletzt bearbeitet von shana-chan am Sa 23.10.10 13:42, insgesamt 4-mal bearbeitet
elundril
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3747
Erhaltene Danke: 123

Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
BeitragVerfasst: Sa 23.10.10 01:17 
bei deiner z-berechnung könntest du das div Matrix rausheben.

ausblenden Quelltext
1:
(a/b) * (c/b) = (a*c) /b					


Und dafür gibts dann die Methode MulDiv, welche schneller ist als eine multiplikation mit anschließender Division durch delphi. ;) Eben so wie ich gepostet habe. ;)

btw: so wie du das try finally verwendest hat es gar keinen sinn.

lg elundril

_________________
This Signature-Space is intentionally left blank.
Bei Beschwerden, bitte den Beschwerdebutton (gekennzeichnet mit PN) verwenden.
shana-chan Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17



BeitragVerfasst: Sa 23.10.10 01:28 
user profile iconelundril hat folgendes geschrieben Zum zitierten Posting springen:
bei deiner z-berechnung könntest du das div Matrix rausheben.

ausblenden Quelltext
1:
(a/b) * (c/b) = (a*c) /b					


Da spuckt er mir nurnoch ein schwarzes Bild aus?

user profile iconelundril hat folgendes geschrieben Zum zitierten Posting springen:
Und dafür gibts dann die Methode MulDiv, welche schneller ist als eine multiplikation mit anschließender Division durch delphi. ;) Eben so wie ich gepostet habe. ;)

lg elundril


Und hier eine Felermeldung (Zugriffsverletzung)?

Naja.. hab mir dan gedacht: Das bischen rechnen wird der jetzt wohl noch abkönnen.
elundril
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3747
Erhaltene Danke: 123

Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
BeitragVerfasst: Sa 23.10.10 01:36 
:autsch: hast recht. das distributivgesetz gilt ja nur bei (a+b)*(a+c). mein fehler, sorry!

//Edit: Könnte dir vielleicht CreatecompatibleBitmap(GetWindowDC(GetForegroundWindow), width, height); einen Geschwindigkeitsvorteil bieten. Eventuell umgeht das das BitBtl und du bekommst ein fix und fertiges Bitmap zurückgeliefert. Bzw das Handle auf ein Bitmap und das wiederrum bietet das ganze Zeug fürs Scanline.

lg elundril

_________________
This Signature-Space is intentionally left blank.
Bei Beschwerden, bitte den Beschwerdebutton (gekennzeichnet mit PN) verwenden.
shana-chan Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17



BeitragVerfasst: Sa 23.10.10 02:26 
user profile iconelundril hat folgendes geschrieben Zum zitierten Posting springen:
CreatecompatibleBitmap(GetWindowDC(GetForegroundWindow), width, height);


Bekomme ich nur schwarz/weiss. Oder ich mach was falsch.

Ich hab
BitBlt(d.Canvas.Handle, 0, 0, d.Width, d.Height, DC, 0, 0, SRCCOPY) ;
in
d.Handle:=CreatecompatibleBitmap(GetWindowDC(GetForegroundWindow), d.width, d.height); <- Schwarz
oder
d.Canvas.Handle:=CreatecompatibleBitmap(GetWindowDC(GetForegroundWindow), d.width, d.height); <- Weiss
geändert.
elundril
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3747
Erhaltene Danke: 123

Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
BeitragVerfasst: Sa 23.10.10 03:27 
Hmm, mein Fehler. Ich hab gerade nochmal nachgesehen und bin draufgekommen das in der nacht wohl mein Englisch nachlässt. Dieser Code erzeugt leider nur ein Bitmap, das wohl noch nicht gefüllt ist, jedoch anscheinend das selbe Pixelformat usw wie der DeviceContext hat. Mea Culpa.

lg elundril

_________________
This Signature-Space is intentionally left blank.
Bei Beschwerden, bitte den Beschwerdebutton (gekennzeichnet mit PN) verwenden.