Entwickler-Ecke
Multimedia / Grafik - JPEG verändern
ShinShan - So 13.08.06 22:04
Titel: JPEG verändern
Hi ich habe viele Jpg-Images auf ein Formular mit zufälliger Position erzeugen lassen, und möchte nun, wenn man auf ein entsprechendes Bild clickt dieses ändern. Sprich ein neues an die selbe Position Laden.
Die Daten über die Position der einzelnen Bilder habe ich in einem Array gespeichert.
Ich weis nur nicht wie ich das Bild raus bekommen soll, auf das geklickt wurde. Hab schon viel mit dem Sender des TImages rumprobiert. Aber wenn ich es mit
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var jpg:TJPEGImage; begin try TImage(Sender).Picture.LoadFromFile('E:\desktop\Memorie\Bilder\25.jpg'); except showmessage('danaben'); end; end; |
versucht, aber da ändert sich nichts, wenn ich wenn ich drauf klicke.
alias5000 - So 13.08.06 22:50
Benutze doch einfach entsprechende Ereignisse der einzelnen TImages
Also OnClick/OnMosueDown/OnMosueUp von jedem TImage
Gruß
alias5000
GSE - Mo 14.08.06 00:08
der Code muss ins MouseDown der Images nich das der Form
mfg
GSE
ShinShan - Mo 14.08.06 15:00
danke shcon mal für die Antworten.
Ich glub es ist besser wenn ich hier mal den ganzen Code anzeigen lasse, damit ihr seht, wie das alles funzt bzw. nicht funzt ;)
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:
| var Form1: TForm1; Karte: array[1..25] of Bild;
...
procedure TForm1.Kartenlegen; var i,j:byte; jpg:TJPEGImage; begin for i:=1 to 25 do begin for j:=1 to 2 do begin Karte[i].Bild:=TImage.Create(self); Karte[i].Bild.Parent:=self; Karte[i].Bild.Left:=random(639)+1; Karte[i].Bild.Top:=random(479)+1; Karte[i].vorne:=inttostr(i); Karte[i].wo.X:=random(639)+1; Karte[i].wo.Y:=random(479)+1; jpg:=TJPEGImage.create; jpg.LoadFromFile('E:\desktop\Memorie\Bilder\26.jpg'); Karte[i].Bild.Picture.Assign(jpg); jpg.free; end; end; end;
procedure TForm1.ImageMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var jpg:TJPEGImage; i:byte; begin for i:=1 to 25 do begin if (Karte[i].wo.X<=X) and (Karte[i].wo.X+30>=X) then begin if (Karte[i].wo.Y<=Y) and (Karte[i].wo.Y+40>=Y) then begin Karte[i].Bild:=TImage.Create(self); Karte[i].Bild.Parent:=self; Karte[i].Bild.Left:=Karte[i].wo.X; Karte[i].Bild.Top:=Karte[i].wo.Y; jpg:=TJPEGImage.create; jpg.LoadFromFile('E:\desktop\Memorie\Bilder\'+inttostr(i)+'.jpg'); Karte[i].Bild.Picture.Assign(jpg); end else showmessage('daneben'); end else showmessage('daneben'); end; end;
initialization randomize;
end. |
Wieso läd der das neue Bild nicht rein, bzw. geht garnicht in die Prozedur um zu testen ob man mit der Maus getroffen hat?
Narses - Mo 14.08.06 15:06
Moin!
Zwei Sachen auf Anhieb:
- Warum packst du die Bilder nicht in eine Image-List? Ist doch viel einfacher zu handeln... ;)
- Du erzeugst da andauernd Images, wann gibst du die denn wieder frei? :gruebel:
cu
Narses
ShinShan - Do 17.08.06 19:00
@ Nerses:
Leider weis ich nicht wie ich eine Image-List handle :)
so ist es dann mit den einzelnen Bildern erstmal einfacher für mich gewesen.
Was sind denn die Vorteile von soner Image-List?
Und die Freiganbe, hab ich im close-event.
Oder gehört die in das destroy-event?
Raffo - Do 17.08.06 19:04
Na ja, ich für meinen Teil würde sagen, es wird eh "destroyed" wenn das Programm beendet wird. Wichtig wäre das nur, wenn Dein Programm aufm Server läuft und es ständig an wäre...
ShinShan - Do 17.08.06 22:09
Ja aber zurück zu meiner Frage:
Ich hab jetzt mit
Getcursorpos
die Mausposition geholt und vergleiche dann, ob ein Bild getroffen wurde.
Aber irgendwie treffe ich auch die Bilder, wenn ich nicht drauf klicke *kopfkratz*
Kann das an Getsursorpos liegen?
Meine Form füllt nämlich nicht den ganzen Bildschirm aus.
Vielleicht geht aber Getcursorpos davon aus.
ich stelle mal den gesammten code rein
Ich hoffe er erklärt sich ein wenig von alleine
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:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, jpeg, ExtCtrls, ImgList;
type Bild = record vorne:string; Bild:TImage; wo:TPoint; end; TForm1 = class(TForm) Edit1: TEdit; Button1: TButton; Label1: TLabel; procedure Button1Click(Sender: TObject); procedure Kartenlegen; procedure ImageMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure ImageClick(Sender:TObject); private gabe:integer; public end;
var Form1: TForm1; Karte: array[1..50] of Bild; Spieler: array of byte; implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject); var n:byte; begin try n:=strtoint(edit1.text); except showmessage('Bitte geben Sie keine Buchstaben ein!'); end; if (n>0)and(n<5) then setlength(Spieler,n) else showmessage('Keine Spieler?/zu viele?'); Button1.Visible:=false; Edit1.Visible:=false; Label1.Visible:=false; Kartenlegen; end;
procedure TForm1.Kartenlegen; var i,j:byte; jpg:TJPEGImage; begin for i:=1 to 50 do begin Karte[i].Bild:=TImage.Create(self); Karte[i].Bild.Parent:=self; Karte[i].Bild.Left:=random(639)+1; Karte[i].Bild.Top:=random(479)+1; Karte[i].vorne:=inttostr(i); Karte[i].wo.X:=Karte[i].Bild.Left; Karte[i].wo.Y:=Karte[i].Bild.Top; jpg:=TJPEGImage.create; jpg.LoadFromFile('E:\desktop\Memorie\Bilder\26.jpg'); Karte[i].Bild.OnClick:=ImageClick; Karte[i].Bild.Picture.Assign(jpg); jpg.free; end; end;
procedure TForm1.ImageMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var jpg:TJPEGImage; i:byte; begin
end;
procedure TForm1.ImageClick(Sender:TObject); var i,X,Y,b:integer; jpg:TJPEGImage; p:TPoint; begin GetCursorPos(p); X:=p.X; Y:=p.Y; for i:=1 to 50 do begin if (Karte[i].wo.X<=X) and (Karte[i].wo.X+30>=X) then begin if (Karte[i].wo.Y<=Y) and (Karte[i].wo.Y+40>=Y) then begin if i<=25 then b:=i else b:=i-25; Karte[i].Bild:=TImage.Create(self); Karte[i].Bild.Parent:=self; Karte[i].Bild.Left:=Karte[i].wo.X; Karte[i].Bild.Top:=Karte[i].wo.Y; jpg:=TJPEGImage.create; jpg.LoadFromFile('E:\desktop\Memorie\Bilder\'+inttostr(b)+'.jpg'); Karte[i].Bild.Picture.Assign(jpg); jpg.free; end else showmessage('daneben'); end; end; end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); var i:integer; begin for i:=1 to 50 do Karte[i].Bild.Free; end;
initialization randomize;
end. |
Vorhanden sind am Anfang ein Label, Edit1 (eingabe der Anzahl der Spieler (was bishar noch keine Auswikungen hat, es sei denn ,man gibt einen Buchsatben oder ein eZahl größer als 4 ein), und der LOS-(button1) der alles starten lässt.
Die Bilder die Geladen werden, haben Zahlen als Namen (von 1 bis 26). 26 ist dabei die Rückseite.
ich hoffe ihr seht jetzt etwas durch.
Marco D. - Do 17.08.06 22:17
ShinShan hat folgendes geschrieben: |
Ich hab jetzt mit
Getcursorpos
die Mausposition geholt und vergleiche dann, ob ein Bild getroffen wurde.
Aber irgendwie treffe ich auch die Bilder, wenn ich nicht drauf klicke *kopfkratz*
Kann das an Getsursorpos liegen?
Meine Form füllt nämlich nicht den ganzen Bildschirm aus.
Vielleicht geht aber Getcursorpos davon aus.
|
Dafür gibts die Funktion ScreenToClient. Schau mal in der Hilfe nach.
Narses - Do 17.08.06 23:27
Narses hat folgendes geschrieben: |
Warum packst du die Bilder nicht in eine Image-List? Ist doch viel einfacher zu handeln... |
ShinShan hat folgendes geschrieben: |
Leider weis ich nicht wie ich eine Image-List handle |
---
Raffo hat folgendes geschrieben: |
Na ja, ich für meinen Teil würde sagen, es wird eh "destroyed" wenn das Programm beendet wird. Wichtig wäre das nur, wenn Dein Programm aufm Server läuft und es ständig an wäre... |
:shock: Aha, dann würde ich schrecklich gerne mal dein Zimmer sehen, und wie´s da drin so aussieht... :rofl:
cu
Narses
Raffo - Fr 18.08.06 07:37
@marco, habe folgendes Grundgerüst gefunden:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| function IsMouseOver(Control: TControl): Boolean; var p: TPoint; begin if GetCursorPos(p) then begin p := Control.ScreenToClient(p); Result := (p.X >= 0) and (p.X <= Control.Width) and (p.Y >= 0) and (p.Y <= Control.Height) ; end else Result := False; end; |
@narses, wirklich sehr geistreicher Kommentar, was hat die Virtualität mit der Realität zu tun? Ich würde das in der Realtität eher so vergleichen: Wenn ich meinen Computer ausschalte, brauche ICH die laufenden Programme nicht beenden.
Narses - Fr 18.08.06 09:20
Moin!
Raffo hat folgendes geschrieben: |
Wenn ich meinen Computer ausschalte, brauche ICH die laufenden Programme nicht beenden. |
Windows hat folgendes geschrieben: |
Der Computer wurde das letzte mal nicht ordnungsgemäß heruntergefahren... |
Und wer repariert dann die kaputt gegangenen Files? ;)
Das hat was mit sinnvoller Art und Weise zu tun, man könnte auch "Programmierstil" dazu sagen. Da das hier aber schon fast immer auf einen Glaubenskrieg hinauslaufen wird, spare ich mir Weiteres, will dir aber eine meiner Erkenntnisse nicht vorenthalten: "Geht doch" ist der Programmierstil, der dir langfristig die meisten Probleme bereiten wird. :|
cu
Narses
heinze - Fr 18.08.06 10:44
Zitat: |
Und wer repariert dann die kaputt gegangenen Files? |
Es gehen doch keine Kaputt?
Windows schickt an alle Programme den Befehl sich zu Beenden, und sofern sich keins extrem dagegen auflehnt fährt sich der PC dan runter ohne das ich Programme wie WinAmp, ICQ, bzw 20 andere Hintergrundprozesse selbst beenden mus.
Soweit ich es Richtig verstanden habe macht Delphi selbiges, sofern das Program richtig beendet wird und nicht bei testläufen einfach abgebrochen wird (wegen Endlosschleife usw) was nach einigen male dan ne Meldung bringt das der Speicher zu voll ist und man dan Delphi selbst neu starten muss. (So gings mir bei Datenbanken)
Zitat: |
Wenn ich meinen Computer ausschalte, brauche ICH die laufenden Programme nicht beenden. |
Er hat ja nie behauptet das sie niemand beendet, nur das er selbst es nicht tut.
Optimiert wirds wens erstmal überhaupt richtig läuft denk ich mir bei sowas.
ShinShan - Mi 20.09.06 22:17
Ich hab das ganze jetzt malso gelöst.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin Klick.X:=X; Klick.Y:=Y; klick:=ScreenToClient(ClientToScreen(klick)); showmessage(inttostr(klick.x)+'/'+inttostr(klick.y)); end; |
Das Problem ist jetzt nur noch, dass mir an einigen Stellen des Bildschirms keine Rückgabe gegeben wird, welche Koordinaten der Klcik hatte.
Das ist volkommen unabhängig davon, ob ich auf ein Bild klicke, das erstellt wurde oder nicht.
Was kann daran nur falsch sein?????
Die Idee mit dem ScreenToClient war trotzdem super!
DANKE nochmal
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!