Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Do Jul 03, 2025 04:14

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 11 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Screenshot machen
BeitragVerfasst: Fr Dez 18, 2009 14:03 
Offline
DGL Member
Benutzeravatar

Registriert: Do Jul 23, 2009 04:33
Beiträge: 157
Programmiersprache: Turbo Delphi Pro
Moinsen, ich bins mal wieder (nach längerer Zeit ^^). Ich versuche einen Screenshot meiner Szene zu speichern, aber das gelingt nicht ganz. Manchmal funktioniert es, aber manchmal auch nicht (wohl abhängig vom Seitenverhältnis des Fensters). Hier meine Funktion und die gemessenen Verhältnisse:

Code:
  1. procedure TfHauptfenster.Screenshot1Click(Sender: TObject);
  2.   type
  3.     pFarbe = ^tFarbe;
  4.     tFarbe = array[0..2] of Byte;
  5.   var
  6.     titel: string;
  7.     x,y: Integer;
  8.     daten: Pointer;
  9.     farbe: tFarbe;
  10.     zeiger: pFarbe;
  11.     bild: TBitmap;
  12.     jp_bild: tJPegImage;
  13. begin
  14.   titel := caption;
  15.   bild := TBitmap.Create;
  16.   bild.Width := ClientWidth;
  17.   bild.Height := ClientHeight;
  18.   getMem(daten,clientwidth*clientheight*3);
  19.  
  20.   render(false);
  21.   glReadPixels(0,0,clientWidth,ClientHeight,GL_RGB,GL_UNSIGNED_BYTE,Daten);
  22.   zeiger := daten;
  23.   for y := ClientHeight -1 downto 0 do
  24.     begin
  25.       for x := 0 to clientWidth -1 do
  26.         begin
  27.           farbe := pFarbe(zeiger)^;
  28.           bild.Canvas.Pixels[x,y] := RGB(farbe[0],farbe[1],farbe[2]);
  29.           inc(zeiger);
  30.         end;
  31.       caption := intToStr(round((100/clientWidth)*y))+'%';
  32.     end;
  33.  
  34.   bild.Canvas.TextOut(10,10,intToStr(ClientWidth)+','+IntToStr(ClientHeight));
  35.  
  36.   jp_bild := TJpegImage.Create;
  37.   jp_bild.Assign(bild);
  38.   jp_bild.SaveToFile(extractFileDir(paramstr(0))+'\screen.jpg');
  39.   jp_bild.Free;
  40.   bild.Free;
  41.   caption := titel;
  42. end;


Zitat:
697,675 nein
697,671 nein
706,668 nein
706,665 nein

696,659 ja (Screenshot hat gefunzt)


Irgendwie gehe ich mit dem was in "Daten" abgelegt ist wohl falsch um, aber ich steig da nicht durch. Wär cool wenn jemand sehen könnte wo der Wurm drin ist.

Winterliche Grüße
Tilman

_________________
Bringe einen Menschen zum grübeln, dann kannst du heimlich seinen Reis essen.
(Koreanisches Sprichwort)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Screenshot machen
BeitragVerfasst: Fr Dez 18, 2009 14:24 
Offline
DGL Member
Benutzeravatar

Registriert: Di Apr 29, 2008 18:56
Beiträge: 1213
Programmiersprache: Delphi/FPC
Hey,

ich hab den Fehler nich gefunden, aber ich hab das für dich:
Code:
  1. function FormularScreenShot(Bmp: TBitmap; h : hWnd): Boolean;
  2. var
  3.   Rec: TRect;
  4.   iWidth, iHeight: Integer;
  5. begin
  6.   with Bmp do try
  7.     GetWindowRect(h, Rec);
  8.  
  9.     iWidth  := Rec.Right - Rec.Left;
  10.     iHeight := Rec.Bottom - Rec.Top;
  11.  
  12.     Width := iWidth;
  13.     Height := iHeight;
  14.  
  15.     BitBlt(Canvas.Handle, 0, 0, iWidth, iHeight, GetWindowDC(h), 0, 0, SRCCOPY);
  16.  
  17.     Result := True;
  18.   finally
  19.     ReleaseDC(h, GetWindowDC(h));
  20.   end;
  21. end;

geht das auch? Ichhabs grad probiert: funzt bei mir.

MfG Bergmann.

_________________
Aktuelle Projekte: BumpMapGenerator, Massive Universe Online
Auf meiner Homepage gibt auch noch paar Projekte und Infos von mir.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Screenshot machen
BeitragVerfasst: Fr Dez 18, 2009 14:39 
Offline
DGL Member
Benutzeravatar

Registriert: Do Jul 23, 2009 04:33
Beiträge: 157
Programmiersprache: Turbo Delphi Pro
Hm, ich bekomme so leider nur Menü + Titelleiste aber nicht den OpenGL-Bereich. Der bleibt einfach Grau.

_________________
Bringe einen Menschen zum grübeln, dann kannst du heimlich seinen Reis essen.
(Koreanisches Sprichwort)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Screenshot machen
BeitragVerfasst: Fr Dez 18, 2009 14:45 
Offline
DGL Member
Benutzeravatar

Registriert: Di Apr 29, 2008 18:56
Beiträge: 1213
Programmiersprache: Delphi/FPC
Hast du als Handle das der Form übergeben?

_________________
Aktuelle Projekte: BumpMapGenerator, Massive Universe Online
Auf meiner Homepage gibt auch noch paar Projekte und Infos von mir.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Screenshot machen
BeitragVerfasst: Fr Dez 18, 2009 14:48 
Offline
DGL Member
Benutzeravatar

Registriert: Do Jul 23, 2009 04:33
Beiträge: 157
Programmiersprache: Turbo Delphi Pro
Ja, wie gesagt das Fenster selbst wird ja auch abgebildet. Ist aber nicht so wichtig ich mach erstmal andere Sachen.

_________________
Bringe einen Menschen zum grübeln, dann kannst du heimlich seinen Reis essen.
(Koreanisches Sprichwort)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Screenshot machen
BeitragVerfasst: Fr Dez 18, 2009 15:48 
Offline
DGL Member
Benutzeravatar

Registriert: Di Apr 29, 2008 18:56
Beiträge: 1213
Programmiersprache: Delphi/FPC
Hey,

wenn du nur einen ScreenShot des Viewports haben willst, dann kannst du auch glBitmap nehmen, da gibts ne Funktion-GrabScreen oder so. Un dann kannst du's einfach mit SaveToFile speichen...

€: mir is grad nochwas aufgefallen, erhöh dein Zeiger mal so:
Code:
  1. inc(PByte(Zeiger), 3);



MfG Bergmann.

_________________
Aktuelle Projekte: BumpMapGenerator, Massive Universe Online
Auf meiner Homepage gibt auch noch paar Projekte und Infos von mir.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Screenshot machen
BeitragVerfasst: Mi Sep 01, 2010 16:29 
Offline
DGL Member
Benutzeravatar

Registriert: Do Jul 23, 2009 04:33
Beiträge: 157
Programmiersprache: Turbo Delphi Pro
So, nach langer Pause hat sich das Problem erneut gestellt, ich hab es jetzt aber glaub ich selber lösen können. Ich poste die Lösung für andere die das selbe Problem haben, und falls ein Profi drüberschauen könnte wär das auch ganz toll... ich hatte nämlich immer mal wieder Stackoverflows, seit der "Lösung" zwar nicht mehr, aber so 100% sicher bin ich mir noch nicht ^^

Also die Lösung war:
Code:
glPixelStoref(GL_PACK_ALIGNMENT,1);


Und hier der Beispielcode:
Code:
procedure TForm1.Screenshot1Click(Sender: TObject);
  var
    pixels: array of Byte;
    x,y: integer;
    n: Integer;
    VP: array[0..3] of Integer;
begin
  render;
  glGetIntegerv(GL_VIEWPORT, @VP);
  glPixelStoref(GL_PACK_ALIGNMENT,1);
  setLength(pixels,VP[2]*VP[3]*3);
  glReadPixels(0,0,VP[2],VP[3],
               GL_RGB,GL_UNSIGNED_BYTE,@pixels[0]);

  form3.Image1.Picture.Bitmap.Width := VP[2];
  form3.Image1.Picture.Bitmap.Height := VP[3];
  n := 0;
  for y := VP[3]-1 downto 0 do
    for x := 0 to VP[2]-1 do
      begin
        form3.Image1.Canvas.Pixels[x,y] :=
          RGB(pixels[n],pixels[n+1],pixels[n+2]);
        inc(n,3);
      end;
end;

_________________
Bringe einen Menschen zum grübeln, dann kannst du heimlich seinen Reis essen.
(Koreanisches Sprichwort)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Screenshot machen
BeitragVerfasst: Do Sep 02, 2010 18:25 
Offline
Guitar Hero
Benutzeravatar

Registriert: Do Sep 25, 2003 15:56
Beiträge: 7810
Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Hast du das mal mit dem Beitrag im Wiki abgeglichen?

Siehe: Screenshot

_________________
Blog: kevin-fleischer.de und fbaingermany.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Screenshot machen
BeitragVerfasst: Do Sep 02, 2010 18:48 
Offline
DGL Member
Benutzeravatar

Registriert: Do Jul 23, 2009 04:33
Beiträge: 157
Programmiersprache: Turbo Delphi Pro
Habe ich, hat mir allerdings mein Problem auch nicht gelöst, da dort Pack_Allingment nicht verwendet wird. Warum es dort ging, und bei mir nicht, dürfte daran gelegen haben: dort werden RGBA-Werte ausgelesen, und die sind natürlich automatisch im 4-Byte-Muster angeordnet, so dass es keine Probleme gibt, während meine 3Byte-RGB-Werte eben je nach width und height gelegentlich durch Zusätzliche Bytes "aufgefüllt" wurden, was Stackoverflow und falsche Ergebnisse brachte. Natürlich hätte ich auch einfach RGBA Werte verwenden können... aber ich wollte ja auch wissen was ich falsch mache ^^ Das Tut an sich wollte ich nicht einsetzen, da ich statt den Header selbst zu schreiben die Infos einfach in ein TBitmap schreibe und dieses in ein JpegImage konvertiere und schreibe.

_________________
Bringe einen Menschen zum grübeln, dann kannst du heimlich seinen Reis essen.
(Koreanisches Sprichwort)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Screenshot machen
BeitragVerfasst: Fr Sep 03, 2010 12:59 
Offline
Guitar Hero
Benutzeravatar

Registriert: Do Sep 25, 2003 15:56
Beiträge: 7810
Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Sehr gute Erklärung. Kannst du da mal einen Hinweis im Wiki ergänzen, damit andere nicht den selben Fehler machen.

_________________
Blog: kevin-fleischer.de und fbaingermany.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Screenshot machen
BeitragVerfasst: Sa Sep 04, 2010 04:16 
Offline
DGL Member
Benutzeravatar

Registriert: Do Jul 23, 2009 04:33
Beiträge: 157
Programmiersprache: Turbo Delphi Pro
Okay, ich habe mal im Screenshot und im glReadPixels Artikel jeweils diesen vorsichtigen Hinweis ergänzt: {{Hinweis|Möchte man, dass die Pixeldaten hintereinanderweg im Speicher erscheinen, so sollte man glPixelStoref(GL_PACK_ALIGNMENT,1) setzen, ansonten werden die Daten je nach Format durch Pixelstore weiter formatiert.}}

P.S. Der oben genannte Algo von mir läuft einwandfrei, ich hab jetzt die Zündende Idee gehabt wie ich ihn testen kann, und einfach width*height*3+1 Byte reserviert, und dann [width*height*3-1] und [width*height*3] jeweils mit einer Prüfzahl beschrieben; ergebnis war das erste Prüfzeichen wurde durch glReadPixels überschrieben, das zweite wie erwartet in Ruhe gelassen - alles okay =)

_________________
Bringe einen Menschen zum grübeln, dann kannst du heimlich seinen Reis essen.
(Koreanisches Sprichwort)


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 11 Beiträge ] 
Foren-Übersicht » Programmierung » Einsteiger-Fragen


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.008s | 15 Queries | GZIP : On ]