AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Bilder laden ohne anzuzeigen - keine Größen vorgabe

Bilder laden ohne anzuzeigen - keine Größen vorgabe

Ein Thema von Destroyer446 · begonnen am 14. Jun 2011 · letzter Beitrag vom 16. Jun 2011
Antwort Antwort
Destroyer446

Registriert seit: 17. Jan 2011
67 Beiträge
 
#1

AW: Bilder laden ohne anzuzeigen - keine Größen vorgabe

  Alt 14. Jun 2011, 18:25
// Edit: Bereichsprüfung aktiviert. - Ergebnis: "ERangeError with message 'Range check error'."
Wieso überschreitet er Array wenn ich Low() - High() abfrage?
// Edit2: Er bricht bei idx := Bmp1.Canvas.Pixels[i1,i2];
FBild1[idx] := FBild1[idx] + 1; ab?


Kompletter Code:
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TStringDynArray = array of String;
  TForm1 = class(TForm)
    Image1: TImage;
    Image2: TImage;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Label1: TLabel;
    Label2: TLabel;
    OpenDialog1: TOpenDialog;
    OpenDialog2: TOpenDialog;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Bmp1, Bmp2: TBitmap;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
 sl: TStringList;
 i1, i2, idx: Integer;
 FBild1, FBild2: array of Integer;
 S1: String;
begin
 If (Label1.Caption = 'Bild1: * Kein Bild geladen *') or (Label2.Caption = 'Bild2: * Kein Bild geladen *') then
 begin
  Application.MessageBox('Du hast nicht beide Bilder geladen.', 'Nicht beide Bilder geladen', MB_ICONERROR or MB_OK);
  Exit;
 end;
 sl := TStringList.Create;
 S1 := '';
 // FBild1 initialisieren
 // BGR 3 Byte x 8 = 24 Bit = 16777216 verschiedene Summen
 SetLength(FBild1, 2 shl 24 + 1);
 // zufälligen Inhalt des Arrays mit 0 löschen
 FillChar(FBild1[0], SizeOf(FBild1[0]) * Length(FBild1), #0);
 // das ganze noch mal für FBild2...
 SetLength(FBild2, 2 shl 24 + 1);
 FillChar(FBild2[0], SizeOf(FBild2[0]) * Length(FBild2), #0);
 sl.Add('*** Bild1 ***');
 sl.Add('');
 for i1 := 0 to Bmp1.Height - 1 do
 begin
  for i2 := 0 to Bmp1.Width - 1 do
  begin
   // nur einmal auf Pixels zugreifen = doppelte Geschwindigkeit
   idx := Bmp1.Canvas.Pixels[i1,i2];
   FBild1[idx] := FBild1[idx] + 1;
   // das ganze noch mal für Bild2...
   idx := Bmp2.Canvas.Pixels[i1,i2];
   FBild2[idx] := FBild2[idx] + 1;
  end;
 end;
 For i1 := Low(FBild1) to High(FBild1) do
 begin
  If FBild1[i1] <> 0 then
   sl.Add('Farbwert: '+IntToStr(i1)+'; Vorhanden: '+IntToStr(FBild1[i1])+'x');
  sl.SaveToFile('C:\TestFile.txt');
 end;
 sl.Add('');
 sl.Add('*** Bild2 ***');
 sl.Add('');
 For i2 := Low(FBild2) to High(FBild2) do
 begin
  If FBild2[i2] <> 0 then
   sl.Add('Farbwert: '+IntToStr(i2)+'; Vorhanden: '+IntToStr(FBild2[i2])+'x');
 end;
 S1 := InputBox('Vergleich erfolgreich abgeschlossen.'#10'Wohin soll das Ergebnis gespeichert werden?', 'Vergleich abgeschlossen', 'C:\Bildervergleich\Ergebnisse\Vergleich 1.txt');
 If ForceDirectories(ExtractFileDir(S1)) then
 begin
  sl.SaveToFile(S1);
  ShowMessage('Ergebnis wurder erfolgreich gespeichert!');
 end
 else
  ShowMessage('Ergebnis konnte nicht gespeichert werden.'#10'Fehlermeldung: Pfad existiert nicht.');
 sl.Free;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 If OpenDialog1.Execute then
 begin
  Bmp1.LoadFromFile(OpenDialog1.FileName);
  Label1.Caption := 'Bild1: '+ExtractFileName(OpenDialog1.FileName);
 end;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
 If OpenDialog2.Execute then
 begin
  Bmp2.LoadFromFile(OpenDialog2.FileName);
  Label2.Caption := 'Bild2: '+ExtractFileName(OpenDialog2.FileName);
 end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 Bmp1 := TBitmap.Create;
 Bmp2 := TBitmap.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 Bmp1.Free;
 Bmp2.Free;
end;

end.
Button1 = Bilder vergleichen
Button2 = Bild 1 laden
Button3 = Bild 2 laden

Ich find da kein Fehler^^

Geändert von Destroyer446 (14. Jun 2011 um 18:51 Uhr)
  Mit Zitat antworten Zitat
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Bilder laden ohne anzuzeigen - keine Größen vorgabe

  Alt 14. Jun 2011, 22:09
Weil idx -1 sein kann (wenn er den Pixel nicht auslesen kann) und du dir damit dein array abschießt.

Weil du kein setLength(Fbild,0) hast und du damit MegaByteweise Speicherlöcher produzierst.

Mal so unter uns, bist du beratungsresistent?
Ich habe dir im letzten Thread eine Lösung auf dem Präsentierteller serviert.
  Mit Zitat antworten Zitat
CCRDude

Registriert seit: 9. Jun 2011
678 Beiträge
 
FreePascal / Lazarus
 
#3

AW: Bilder laden ohne anzuzeigen - keine Größen vorgabe

  Alt 15. Jun 2011, 08:18
@Bjoerk: Auch wenns nicht zum eigentlichen Topic gehört: ich bin ja auch so einer, der jedes dynamische Array zum Schuss wieder auf Länge Null setzt, meine aber irgendwo schon mal gehört zu haben, daß dies nicht nötig sei (zumindest lokal wie hier), und das sogar mit FastMM getestet zu haben. Hast Du mehr Infos dazu, daß das wirklich Speicherlöcher produziert?
  Mit Zitat antworten Zitat
Benutzerbild von Deep-Sea
Deep-Sea

Registriert seit: 17. Jan 2007
907 Beiträge
 
Delphi XE2 Professional
 
#4

AW: Bilder laden ohne anzuzeigen - keine Größen vorgabe

  Alt 15. Jun 2011, 08:25
Natürlich produziert so etwas keine Speicherlöcher. Sobald die letzte Referenz auf ein dyn. Array (oder einen Record) weg ist - was hier beim verlassen der Prozedur der Fall ist - wird der Speicher freigegeben (außer ich reserviere ihn mir selbst mittels GetMem, New, etc.). Eigentlich bekannt?!
Chris
Die Erfahrung ist ein strenger Schulmeister: Sie prüft uns, bevor sie uns lehrt.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.401 Beiträge
 
Delphi 12 Athens
 
#5

AW: Bilder laden ohne anzuzeigen - keine Größen vorgabe

  Alt 15. Jun 2011, 08:50
Interfaces, dyn. Arrays und Strings unterliegen einer Referenzzählung, welche es dann automatisch freigibt.
Records und static Arrays liegen direkt in der Variable und werden zusammen mit dieser entsorgt.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
CCRDude

Registriert seit: 9. Jun 2011
678 Beiträge
 
FreePascal / Lazarus
 
#6

AW: Bilder laden ohne anzuzeigen - keine Größen vorgabe

  Alt 15. Jun 2011, 09:34
Danke

Da war doch mal so ein älterer Bug (Delphi 2006 evtl.? Wo es die Ausnahme gab, daß die Referenzzählung im initialization-Teil von Units nicht korrekt funktionierte?) bin ich da etwas sensibel. Gut zu wissen daß ich nicht falsch lag
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.401 Beiträge
 
Delphi 12 Athens
 
#7

AW: Bilder laden ohne anzuzeigen - keine Größen vorgabe

  Alt 15. Jun 2011, 10:11
Der Delphicompiler umgibt die Funktions/Procedur/Methoden-Rümpfe mit einem Try-Finally, wenn derartige Typen in den lokalen Variablen, bzw. als Parameter (außer bei Const und Var) liegen.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Antwort Antwort

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:50 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz