Autor Beitrag
trm
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 491
Erhaltene Danke: 19

Windows 7x64
Delphi 7
BeitragVerfasst: Mi 20.01.10 01:34 
Ich versuche mich an einem (sicherlich) einfachen Problem. Wenn ich 2 TImage auf einem Formular habe und beide die gleichen Eigenschaften besitzen, funktioniert der unten stehende Code leider nicht so, wie er soll :(

Image1 hat ein Bild, Image2 nicht.
Edit1 und Edit2 haben Zahlen als Wert.

Herauskommen soll am Ende eigentlich das Originalbild, jedoch mit einem vertauschten Raster. So in etwa:

Original: Moderiert von user profile iconNarses: siehe Bild1 im Anhang
Ergebnis: Moderiert von user profile iconNarses: siehe Bild2 im Anhang

(Falls die Links nicht mehr funktionieren, habe ich die Bilder gelöscht)
Moderiert von user profile iconNarses: Und damit das nicht passiert, habe ich die Bilder hochgeladen. ;)

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:
procedure TForm1.Panel2Click(Sender: TObject);
var
  reihen, spalten: Integer;
  x, y: integer;
  dx, dy: Integer;
  dx2, dy2: Integer;
  Dummy_BitMap: TBitmap;
  r1, r2, r3: TRect;
begin

  randomize;
  reihen := strtoint(edit1.Text);
  spalten := strtoint(edit2.Text);

  Dummy_BitMap := TBitMap.Create;
  Dummy_BitMap.Width := (Image1.Width div reihen);
  Dummy_BitMap.Height := (Image1.Height div spalten);

  Image2.Picture := Image1.Picture;

  for x := 0 to reihen do
    for y := 0 to spalten do
    begin
      dx := (Image1.Width div reihen) * x;
      dy := (Image1.Height div spalten) * y;

      dx2 := (Image1.Width div reihen) * (random(reihen - 1) + 1);
      dy2 := (Image1.Height div spalten) * (random(spalten - 1) + 1);

      r1 := Rect(dx, dy, dx + Dummy_BitMap.Width, dy + Dummy_BitMap.Height);
      r2 := Rect(dx2, dy2, dx2 + Dummy_BitMap.Width, dy2 + Dummy_BitMap.Height);
      r3 := Rect(00, Dummy_BitMap.Width, Dummy_BitMap.Height);

      Dummy_BitMap.Canvas.CopyRect(r3, Image2.Canvas, r1);
      Image2.Canvas.CopyRect(r2, Image2.Canvas, r1);
      Image2.Canvas.CopyRect(r1, Dummy_BitMap.Canvas, r3);

    end;

  Dummy_BitMap.Free;

end;
Einloggen, um Attachments anzusehen!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19326
Erhaltene Danke: 1749

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 20.01.10 07:18 
user profile icontrm hat folgendes geschrieben Zum zitierten Posting springen:
(Falls die Links nicht mehr funktionieren, habe ich die Bilder gelöscht)
Warum hängst du die Bilder nicht einfach im Forum an?

Ein Problem dürften diese Zeilen sein:
ausblenden Delphi-Quelltext
1:
2:
      dx2 := (Image1.Width div reihen) * (random(reihen - 1) + 1);
      dy2 := (Image1.Height div spalten) * (random(spalten - 1) + 1);
Denn wenn ich das richtig sehe (getestet hab ichs jetzt nicht), werden damit die letzte Spalte und Zeile nicht erreicht, so dass diese unverändert bleiben. Hast du es einmal ohne das -1 und +1 versucht?

Der andere Faktor sind die Integerdivisionen. Dadurch, dass du nicht rundest, bleibt der Rest der Division auch als unveränderter Streifen übrig.

Du hast ja leider nicht dazugeschrieben wo eigentlich das Problem liegt, aber ich rate einmal, dass das das Problem sein könnte.
trm Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 491
Erhaltene Danke: 19

Windows 7x64
Delphi 7
BeitragVerfasst: Mi 20.01.10 11:12 
Hi jaenicke,

danke für Deine Antwort.
Ich habe mal ein Beispielproject angehängt sowie ein Bild, wie es aussieht. Kleines Demoproject (rar, 382.7 KB)

Vielleicht findet ja jemand meinen Denkfehler.

Image1 ist nebenbei nur als Korrekturbild auf der Form, ist eigentlich überflüssig.
Einloggen, um Attachments anzusehen!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19326
Erhaltene Danke: 1749

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 20.01.10 11:20 
Zwei Probleme habe ich ja bereits genannt, die sich wie von mir erwartet auswirken.

Zusätzlich kommt bei dir noch dazu, dass du Stretch und kein AutoSize benutzt, aber die Größe der visuellen Komponente für deinen Quelltext benutzt. Dementsprechend passt die bearbeitete Größe natürlich nicht zum gesamten Bild...
Ein dringender Rat: Trenne die Oberfläche vom Programm selbst. Heißt: Schreibe eine Funktion, die zwei Bitmaps bekommt, mache dort die Operation und rufe das nur auf indem du die benötigten Daten übergibst.

Ach ja: Und noch ein Tipp: Wenn du Jpegs benutzt, ist die Exe wesentlich kleiner. ;-)

// EDIT:
Noch was: Warum nennst du deine Variable spalten, wenn du die Breite damit verrechnest und genauso bei reihen? :gruebel:
trm Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 491
Erhaltene Danke: 19

Windows 7x64
Delphi 7
BeitragVerfasst: Mi 20.01.10 12:10 
Hallo :)

Danke, dass Du nochmal drüber geguckt hast.

Autosize und Strech ist ja eigentlich irrelevant, weil das Project ja den Canvas nimmt und nicht auf das Image selbst zugreift.
Ich habe Stretch auch im Moment nur gemacht, damit keine leeren Ränder an den Seiten entstehen.

Der Grund, warum ich hier gepostet habe ist, dass meine Rechnung irgendwie nicht stimmt. Vom logischen her ist m.M. nach zwar alles korrekt, jedoch kommt nicht das Ergebis raus, was ich erhoffe.

Um es nochmal schnell im Kopf nachzuvollziehen:

Image1 ist nur ein Dummy
Image2 wird als Referenz für das Blockweise verschieben von Ausschnitten herangezogen.
Dumm_Bitmap ist ein Puffer.

Zuerst kopiere ich einen sich konstat erhöhenden Teil aus dem Bild in Dummy_Bitmap.
Dann verschiebe ich einen zufälligen Block an die Position, die dem Dummy_Bitmap zugeordnet wurde.
Dann fülle ich den Bereich, der als Basis der zufälligen Verschiebung genutzt wurde mit dem Inhalt von Dummy_Bitmap.

Aber: das Ergebnis sieht man ja leider. Total verhauen.

Es ist auch erstmal egal, ob am Ende was fehlt.. (-1)
Es ist auch erstmal egal, dass die Variablen einen unschönen Namen haben.

Das ist wirklich erst einmal nur ein Versuch, damit ich verstehe, wie es funktioniert.


Gruß
Mathias
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19326
Erhaltene Danke: 1749

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 20.01.10 12:26 
Nimm doch einfach das +1 und -1 raus und setze Autosize statt Stretch, dann wirst du sehen, dass es klappt (abgesehen von den vertauschten reihen / spalten Variablen)... :roll:
Es liegt daran.

Beispiel:
Das Bild in deinem Image ist 500 Pixel groß, das Image 250. So, dein Algorithmus rechnet jetzt mit einer Breite von 250 Pixeln (des Images), zeichnet aber auf ein Bild von 500 Pixeln (des Canvas des Bildes im Image)... Fällt dir etwas auf? ;-)
trm Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 491
Erhaltene Danke: 19

Windows 7x64
Delphi 7
BeitragVerfasst: Mi 20.01.10 14:29 
Naja, zugegeben es sieht proportional schöner aus. Du hast Recht.

Aber dennoch wiederholen sich Teile des Originalbildes als Ausschnitt. Dies ist aber vom rechnerischen her unmöglich, da ich das Original ja von links nach rechts und von oben nach unten durchlaufe. Wieso sind dann also auf einmal einzelne Teile doppelt vorhanden :( ?
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1654
Erhaltene Danke: 244

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Mi 20.01.10 15:12 
Hallo,

wenn Du image2 vorher mit fillrect oder so löschst,statt image1 hinein zu kopieren, siehst Du es.
Deine Zufallszahlen treffen ab und an auf das selbe Feld und es werden also nicht alle Felder beschrieben und man sieht diese zum Teil doppelt oder garnicht mehr.
Ich habe es mal so wie im Anhang gemacht:
Es wird eine Liste aller Rechteckblöcke (Bildausschnitte) gemacht (die Du auch durchgehts in deinen Schleifen) und anschliessend eine Kopie davon gemischt.
Dann wird einfach nacheinander jeder Block des Originals aus Image1 in die Fälschung Image2 kopiert.

Gruß Horst
EDIT:
Oh, ich Narr.
31 (For x= 0..30) mal mischen muss man natürlich nicht. Wollte eigentlich testen wie schnell das geht. Es geht ;-) , aber image2.update war nicht der Schlüssel zum sofortigen Neuzeichnen, ist aber auch unwichtig
Einloggen, um Attachments anzusehen!
trm Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 491
Erhaltene Danke: 19

Windows 7x64
Delphi 7
BeitragVerfasst: Mi 20.01.10 15:48 
Hm, ich habe eben den Fehler gefunden.

Dummy_BitMap.Canvas.CopyRect(r3, Image2.Canvas, r2);

Dort hatte ich als Referenz die ganze Zeit r1 (r eins).
Jetzt gehts.

Horst, bevor ich Dein Beispiel gesehen habe, hatte ich eine ähnliche Idee mit TexOut :)

Danke für Dein Beispiel.

Den Fix für spalten/reihen hatte ich auch schon überlegt, wie ich das hinbekomme. Geht eben nicht anders als dec oder inc :)

Gruß
~Mathias
Einloggen, um Attachments anzusehen!
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1654
Erhaltene Danke: 244

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Mi 20.01.10 17:57 
Hallo,

apropos mischen.Du berechnst Deine zweite Tauschkoordinate ja so:
ausblenden Delphi-Quelltext
1:
2:
      dx2 := (Dummy_BitMap.Width) * (random(reihen));
      dy2 := (Dummy_BitMap.Height) * (random(spalten));

Dadurch kann es vorkommen, das Du Pos 1 mit 3 und später 3 mit 1 tauschst.
Also ist nichts getauscht worden.
Die Wahrscheinlichkeit sollte aber für jede Permutation gleich 1/n! sein. Ist sie hier aber nicht.
Die Wahrscheinlichkeit für ungemischt ist erheblich höher.
Fisher-Yates shuffle, macht das nicht.Das Verfahren tauscht nur mit Postionen gleich oder größer der jetzigen.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
  for y := 0 to spalten-1 do
    for x := 0 to reihen-1 do
    begin
      dx := Dummy_BitMap.Width * x;
      dy := Dummy_BitMap.Height * y;

      dx2 := (Dummy_BitMap.Width) * (random(reihen-x)+x);
      dy2 := (Dummy_BitMap.Height) * (random(spalten-y)+y);

Für die erste von 4 in einer Reihe ist die Wahrscheinlichkeit 1/4 dass nicht getauscht wird, für die 3.te 1/3 ..bis zur letzten 1/1
Macht 1/4!, wie es sein sollte.Bei Dir ist Wahrscheinlichkeit dank einfachen zurückstauschens mindestens (n-1) größer.
Also statt 1/24 als Wahrscheinlichkeit für ein ungemischtes Bild ist es nun 3/24 = 1/8
Stelle mal Spalten auf 1 und schau Dir das mal an.

Gruß Horst
trm Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 491
Erhaltene Danke: 19

Windows 7x64
Delphi 7
BeitragVerfasst: Mi 20.01.10 18:32 
Lieber Horst,

danke für den Hinweis :)

Fisher-Yates shuffle, macht das nicht.

Ich kannte dieses Verfahren bisher nicht.
Das hat mir viel Grübelei erspart :)
(mit Berechnungen hab ich nicht so ;) )

Woher kennst Du das - und wo kann man sowas nachlesen, wenn man nicht weiss, wonach man suchen soll?

Gruß
~M.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19326
Erhaltene Danke: 1749

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 20.01.10 19:54 
user profile icontrm hat folgendes geschrieben Zum zitierten Posting springen:
Woher kennst Du das - und wo kann man sowas nachlesen, wenn man nicht weiss, wonach man suchen soll?
Im Forum, genauer gesagt in der Library :mrgreen:
trm Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 491
Erhaltene Danke: 19

Windows 7x64
Delphi 7
BeitragVerfasst: Do 21.01.10 00:34 
Nur für die Vollständigkeit halber, hier das fertige minitool als source mit binary drin.

Danke an alle Helfer :)

Liebe Grüße
~Mathias

Edit: Virustotalscan-Link: www.virustotal.com/a...215e58546-1264026592
Einloggen, um Attachments anzusehen!