SIGSEGV Fehler bei Laden von JPG und PNG

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
klausi1305
Beiträge: 35
Registriert: Mo 1. Jul 2013, 21:30
OS, Lazarus, FPC: Win 7 Laz 1.0.10
CPU-Target: 32 Bit
Wohnort: Leipzig

SIGSEGV Fehler bei Laden von JPG und PNG

Beitrag von klausi1305 »

Hallo,

ich habe da folgendes Problem:
Ich lade ein Bild, bestimme dessen Ausmaße und erstelle mit denen ein Gitternetz welches für die spätere Verwendung in einen 2d Array verwendet wird.

Das ganze funktioniert mit geladenen BMP Dateien einwandfrei, jedoch bei JPG und PNG Dateien bekomme ich einen SIGSEGV Fehler nachdem der Array erstellt wird. Die nötigen Attribute werden jedoch korrekt ermittelt?!

Code: Alles auswählen

unit Spielfeldeditor;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtDlgs, ExtCtrls;
 
type
 
  { TForm2 }
 
  TForm2 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    Label2: TLabel;
    map: TImage;
    OpenPictureDialog1: TOpenPictureDialog;
    PaintBox1: TPaintBox;
    ScrollBox1: TScrollBox;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure mapPaint(Sender: TObject);
    procedure PaintBox1Paint(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
type
  TSpielfeld = record
    Name     : String[20];
    PosX1    : Integer;       //Oben LinksX
    PosY1    : Integer;       //Oben LinksY
    PosX2    : Integer;       //Unten RechtsX
    PosY2    : Integer;       //Oben RechtsY
  end;
var
   Form2: TForm2;
   Spielfeld : Array of Array of TSpielfeld;
   MapObenLinksX    : Integer;   //Ecke Oben Links Sichtbarer Bereich von Map X
   MapObenLinksY   : Integer;   //Ecke Oben Links Sichtbarer Bereich von Map Y
   MapUntenRechtsX : Integer;   //Ecke Unten Rechts Sichtbarer Bereich von Map X
   MapUntenRechtsY : Integer;   //Ecke Unten Rechts Sichtbarer Bereich von Map Y
   AnzFelderHoehe  : Integer;   //Anzahl Gitterfelder in der Höhe
   AnzFelderBreite : Integer;   //Anzahl Gitterfelder in der Breite
   AnzGesamt       : Integer;  //Gesamtanzahl Gitterfelder zur Bestimmung von Setlength
   Zaehler1, Zaehler2 : Integer;
 
implementation
 
{$R *.lfm}
 
{ TForm2 }
procedure TForm2.Button1Click(Sender: TObject);
begin
{------------Bild laden-------------------------}
  if openpicturedialog1.Execute then
  begin
    map.Picture.LoadFromFile(openpicturedialog1.FileName);
 
{--------Spielfeld Array dynamisch erstellen----------}
     //Größe des Arrays aus Maßen des geladenen Bilds ermitteln, Gittergröße 37x37    dynamisch machen???
             AnzFelderHoehe  := Trunc(Map.Picture.Height/37);    //Felder in der Höhe vom Bild ermitteln
             AnzFelderBreite := Trunc(Map.Picture.Width/37);     //Felder in der Breite vom Bild ermitteln
             AnzGesamt       := AnzFelderBreite*AnzFelderHoehe;  //Höhe x Breite = Gesamtanzahl
             Label2.Caption  := IntToStr(AnzFelderHoehe)+','+IntToStr(AnzFelderBreite)+','+IntToStr(AnzGesamt); //Ausgabe
             Label2.Visible  := True;       //Sichtbar machen
             showmessage('Test');
 
 
             //Array Spielfeld erstellen
             Setlength(Spielfeld,AnzFelderHoehe,AnzFelderBreite);   //Länge des dynamischen 2D Arrays festlegen
             Zaehler1:=-1;        //Zähler für Breite
             Repeat               //Äußere Schleife um Schrittweise Spalten zu füllen
               Inc(Zaehler1);     //Begin bei Spalte 0
               Zaehler2:=-1;      //Zähler für Hoehe
               Repeat             //Innere Schleife um Schrittweise Zeilen zu füllen
                  Inc(Zaehler2);  //Begin bei Zeile 0
                  Spielfeld[Zaehler1,Zaehler2].Name  := IntToStr(Zaehler1);
                  Spielfeld[Zaehler1,Zaehler2].PosX1 := (Zaehler1*37);      //Obere Linke Ecke X
                  Spielfeld[Zaehler1,Zaehler2].PosY1 := (Zaehler2*37);      //Obere Linke Ecke Y
                  Spielfeld[Zaehler1,Zaehler2].PosX2 := ( Spielfeld[Zaehler1,Zaehler2].PosX1+37); //Untere Rechte Ecke X
                  Spielfeld[Zaehler1,Zaehler2].PosY2 := ( Spielfeld[Zaehler1,Zaehler2].PosY1+37); //Untere Rechte Ecke Y
               until Zaehler2 = AnzfelderHoehe-1;
             until  Zaehler1 = AnzFelderBreite-1;
         // Hier kommt SIGSEGV bei Jpg, Png  WTF!!!!
  end;
  {---------------------------------Bildgröße an Scrollbox1 anpassen-------------}
      Map.Left:=0;                            //Image ausrichten
      Map.Top:=0;
      Paintbox1.Left:=0;                      //Paintbox ausrichten
      Paintbox1.Top:=0;
      Paintbox1.Width:=Scrollbox1.Width;
      Paintbox1.Height:=Scrollbox1.Height;
      scrollbox1.Visible:=true;               //Scrollbox sichtbar
 
end;
 
procedure TForm2.FormCreate(Sender: TObject);
begin
  scrollbox1.Visible:=false;
end;
 
procedure TForm2.mapPaint(Sender: TObject);
begin
//{-----Bestimmen des sichtbaren Bereichs vom Spielfeld-------------}
////Berechnung der Koordinaten der Linken oberen Ecke
//  MapObenLinksX  := Scrollbox1.HorzScrollBar.Position;
//  MapObenLinksY  := Scrollbox1.VertScrollBar.Position;
////Berechnung des sichtbaren Bereichs in der Scrollbox von Map
//  MapUntenRechtsX := MapObenLinksX + Scrollbox1.Width - 23;
//  MapUntenRechtsY := MapObenLinksY + Scrollbox1.Height - 23;
////Ausgabe Koordinaten
//  Label1.Caption:=IntToStr(MapObenLinksx)+' '+ IntToStr(MapObenLinksy)+' '+IntToStr(MapUntenRechtsX)+' '+IntToStr(MapUntenRechtsY);
//
end;
 
procedure TForm2.PaintBox1Paint(Sender: TObject);
begin
  //{-------------Gitter 37x37 aus Array auf Paintbox zeichnen-------------------------}
  //           Paintbox1.Canvas.Pen.Color:=CLred;
  //           Zaehler1:=-1;
  //           Repeat
  //             inc(Zaehler1);
  //             Paintbox1.Canvas.MoveTo(Spielfeld[Zaehler1,0].PosX1,0);
  //             Paintbox1.Canvas.lineTo(Spielfeld[Zaehler1,0].PosX1,Paintbox1.Height);
  //           until Zaehler1 = AnzFelderBreite-1;
  //           Zaehler1:=-1;
  //           Repeat
  //             inc(Zaehler1);
  //             Paintbox1.Canvas.MoveTo(0,Spielfeld[0,Zaehler1].PosY2);
  //             Paintbox1.Canvas.lineTo(Paintbox1.Width,Spielfeld[0,Zaehler1].PosY2);
  //           until Zaehler1 = AnzFelderHoehe-1;
end;
 
end.
 

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: SIGSEGV Fehler bei Laden von JPG und PNG

Beitrag von Michl »

Tausche mal:

Code: Alles auswählen

                 until Zaehler2 = AnzfelderBreite-1;
               until  Zaehler1 = AnzFelderHoehe-1;      
dann sollts gehen :)

Zumindest sollte der SIGSEV weg sein, ob die Berechnung dann noch stimmt hab ich mir nicht angeschaut (dass das mal funktioniert hat kann nur daran liegen, dass Breite = Höhe des Bildes war!).

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

klausi1305
Beiträge: 35
Registriert: Mo 1. Jul 2013, 21:30
OS, Lazarus, FPC: Win 7 Laz 1.0.10
CPU-Target: 32 Bit
Wohnort: Leipzig

Re: SIGSEGV Fehler bei Laden von JPG und PNG

Beitrag von klausi1305 »

Besten Dank!!

funktioniert wie gewünscht!! Ich hatte zum Testen immer nur 2x2, 10x10 Bilder verwendet...aahh..

dann war die Frage im Einsteigerforum ja berechtigt

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: SIGSEGV Fehler bei Laden von JPG und PNG

Beitrag von Michl »

Gerne!

Nur als Tip (will nicht wie ein Oberlehrer klingen :wink: ):
Um solche Fehler zu lokalisieren, ist es am einfachsten, zu schauen, was für Werte bei dem Abbruch durch den SIGSEV stehen bleiben. In diesem Fall ganz einfach mit der Maus kurz über einer deiner Variablen stehenbleiben, dann erscheint ein Fenster, worin die aktuellen Inhalte dieser zu sehen ist. Das mit allen Variablen machen, die den SIGSEV evtl. ausgelöst haben könnten und kurz nachdenken bzw. vergleichen, ob dieser Wert sein kann oder nicht sein dürfte.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Antworten