Mehrere Bilder gleichzeitig darstellen



  • Wenn ich das mit TImage und ScrollBox mache dann muss ich halt die Bilder selber anordnen... Das macht mir ListView automatisch. Aber wenns nicht anderst geht, naja.

    Danke

    Basti



  • Hi Basti,

    das ist eigentlich egal ob du Scrollbox oder ListView nimmst. Bei ScrollBox ist es nur eine kleine Berechnung, mit dem Anlegen der Objekte.

    Du schaffst das schon.

    Philipp



  • Hi B@asti

    Du willst sowas wie 'ne Thumbnail- Uebersicht - beliebig viele Bilder in gleicher Groese darstellen mit Scrollfunktion?

    Das mach ich so:

    1: von TPanel ne Kompo (Klasse) ableiten = TImagePanel
    -- In der Kompo liegt (dynamisch in CTor erzeugt) ein TImage
    -- Funktion definieren LoadFromFile, womit 'ne Bilddatei in das Image
    -- geladen wird in TImage. Skalierung proportional berechnet!!!
    -- Das TImage wird passend zu Bildproportionen in Panel 'eingepasst'
    -- Der komplette Dateinamen wird in Property von TImagePanel gespeichert.

    2: von TScrollBox ne Kompo ableiten = TMultiImageScroller
    -- Property fuer Zeilen und Spaltenanzahl (int)
    -- Funktion definieren LoadFromFileList mit Parameter TSringList fuer
    -- die Dateinamen!
    -- Fuer jede Datei (Namen) wird ein TImagePanel erzeugt, Groese berechnet
    -- und in ScrollBox positioniert
    -- LoadFromFile des TImagePanel ausfuehren fuer Anzeige.
    -- Die Anordnung Zeilen / Spaltenweise gemaess Property Zeile / Spaltenanzahl

    Mit den zwei gekoppelten Kompos haste ne Flexible, scrollbare Anzeige fuer beliebig viele Bilder (je nach RAM). geht bei mir mit hunderten Bildern.

    Kritisch ist nur die Skalierung im TImagePanel (Sch****- Rechnerei!)



  • Danke, 🙂
    gute Antwort. Ob ich das hin bekomme?
    Mal sehen.

    MfG
    Basti



  • Hmm, ich bekomm das irgendwie nicht hin. Ich weis ehrlich nicht mal wie ich das richtig angehen soll. Hast du mir vielleicht ein kleines Bsp. oder so?

    MfG
    Basti



  • Hi B@asti

    Wo klemmt's genau?

    Beim TImagePanel oder TMultiImageScroller?

    PS: Ich such mal was 'raus. Kann etwas dauern, ist 'ne grosse Kompo- Sammlung.



  • Probier mal das aus:

    Klasse TImagePanel zum Laden und Anzegen EINES Bitmap- Bildes aus Datei (.BMP)

    Header- Datei:
    
    //---------------------------------------------------------------------------
    class PACKAGE TImagePanel : public TCustomPanel
    {
    private:
    protected:
      AnsiString FFName;
    public:
      TImage *FImage;
                   __fastcall TImagePanel(TComponent* Owner);
                   __fastcall ~TImagePanel(void);
            void __fastcall LoadFromFile(AnsiString FName);
      __property AnsiString FName={read=FFName,nodefault} ;
    __published:
    };
    //---------------------------------------------------------------------------
    
    CPP- Datei:
    //---------------------------------------------------------------------------
    // ValidCtrCheck wird benutzt, um sicherzustellen, daß die erzeugten Komponenten keine
    // rein virtuellen Funktionen haben.
    //
    static inline void ValidCtrCheck(TImagePanel *)
    { new TImagePanel(NULL);
    }
    //---------------------------------------------------------------------------
    __fastcall TImagePanel::TImagePanel(TComponent* Owner)
            : TCustomPanel(Owner)
    { FImage=new TImage(this);
      FImage->Parent=this;
      FImage->Enabled=false;
      FImage->AutoSize=true;
    }
    //---------------------------------------------------------------------------
    __fastcall TImagePanel::~TImagePanel(void)
    { delete FImage;
    }
    //---------------------------------------------------------------------------
    void __fastcall TImagePanel::LoadFromFile(AnsiString FName)
    { Graphics::TPicture *Pic;
      float Zoom;
      FFName=FName;
      {
        FImage->AutoSize=false;
        FImage->Stretch=true;
        try
        {
          Pic=new Graphics::TPicture;
          try
          {
            Pic->LoadFromFile(FName);
            FImage->Hint="";
            if ((float (ClientWidth-2) / float (Pic->Width))<(float (ClientHeight-2) / float (Pic->Height)))
            {
              Zoom=float (ClientWidth-2) / float (Pic->Width);
            }
            else
            {
              Zoom=float (ClientHeight-2) / float (Pic->Height);
            }
            FImage->Width=Pic->Width * Zoom;
            FImage->Height=Pic->Height * Zoom;
            FImage->Left=(ClientWidth-FImage->Width) / 2;
            FImage->Top=(ClientHeight-FImage->Height) / 2;
            FImage->Picture->Assign(0);
            FImage->Canvas->StretchDraw(FImage->ClientRect,Pic->Graphic);
            FImage->Left=(ClientWidth-FImage->Width) / 2;
            FImage->Top=(ClientHeight-FImage->Height) / 2;
          }
          catch(...)
          {
            FFName="";
            Zoom=0;
          }
          delete Pic;
        }
        catch(...)
        {
          FFName="";
          Zoom=0;
        }
      }
    }
    //---------------------------------------------------------------------------
    

    PS: Da koennten 'n paar ueberfluessige Teile d'rin sein! Ist aus einer komplexeren Kompo 'rausgezerrt!



  • Danke schön 🙂 Ich schau es mir mir mal an und hoffe das es was wird. Was muss ich denn noch beachten und wie verwende ich die Klasse/Kompo dann?

    MfG
    Basti



  • Hi B@asti

    Zum Testen:

    Fueg einfach die zwei Teile in die .h und .cpp Datei Der Form des Programms ein.
    (vor den Header der Form!)

    in privat der Form:
    TImagePanel *IP;

    in OnCreate der Form:
    IP=new TImagePanel(this);
    IP->Parent=this;

    in OnDestroy
    delete IP;

    IRGENDWO:

    IP->LoadFromFile("Name der Datei.bmp");

    Voila :p

    PS: Position und Groese des Panel vor Laden einstellen!

    Wenn Du das in richtige Package machst, gehts noch einfacher mit der IDE! Kannste aber spaeter auch noch.



  • Hallo Altenburger,

    ich habe desehen dass du da ein schönes Beispiel gegegeben hast. ich hatte mal mit einem ähnlichen problem zu tun. nun habe ich folgende zeile bei dir gesehen:

    class PACKAGE TImagePanel : public TCustomPanel

    Mir ist aufgefallen, das du PACKAGE verwendest hast. dies hatte ich nicht gemacht. wofür steht das eigentlich, was bringt mir das?

    simon



  • Das Programm lässt sich starten, im Eck habe ich auch das Pannel aber wenn ich dann den Button klicken der "IP->LoadFromFile("IP.bmp");" aufruft bekomme ich eine Zugriffsverletzung im Modul vcl50.bpl. Woran liegt denn das?

    MfG
    Basti



  • @Simon maas

    ka!!!

    Das macht der Compiler 'rein, wenn ich ne Komponente in 'ner Package erstelle!

    Das ist ein Auszug aus 'ner Package!!! Wenn du das so im Projekt machst, brauchste die Angabe nicht

    @B@sti
    Was fuer 'nen Fehler genau? Das angegebene Bild muss gueltig sein - auf Festplatte existieren!

    Lass mal schrittweise ablaufen! Bei welchem Befehl hauts den raus?

    PS: Der Dateiname muss mit kompletten Pfad angegeben sein!!!

    [ Dieser Beitrag wurde am 23.05.2003 um 13:45 Uhr von DerAltenburger editiert. ]



  • Keine Ahnung was ich falsch gemacht hatte, aber jetzt funktioniert es 😉
    Danke

    MfG
    Basti



  • Tja, leider reichen mir meine C++ Kenntnisse incht aus um den Part 2

    2: von TScrollBox ne Kompo ableiten = TMultiImageScroller
    -- Property fuer Zeilen und Spaltenanzahl (int)
    -- Funktion definieren LoadFromFileList mit Parameter TSringList fuer
    -- die Dateinamen!
    -- Fuer jede Datei (Namen) wird ein TImagePanel erzeugt, Groese berechnet
    -- und in ScrollBox positioniert
    -- LoadFromFile des TImagePanel ausfuehren fuer Anzeige.
    -- Die Anordnung Zeilen / Spaltenweise gemaess Property Zeile / Spaltenanzahl

    zu machen, hab es schon mehrfach versucht, finde aber auch irgendwie kein Ansatzpunkt.

    MfG
    Basti



  • Mensch B@sti, wo Du Dich überall rumtreibst 😃
    Ab ins DavidM 1337 Forum mit Dir 😛

    greets, Mc



  • Original erstellt von Clip:
    **Mensch B@sti, wo Du Dich überall rumtreibst 😃
    Ab ins DavidM 1337 Forum mit Dir 😛

    greets, Mc**

    ?



  • Hi B@sti

    Hilft Dir das:

    class PACKAGE TMultiImageScroller : public TScrollBox
    {
    private:
      int Column,Row;
      TList* FImagePanelList;
      void __fastcall SetRow(int Rows);
      void __fastcall SetColumn(int Cols);
    protected:
      TStringList* Files;
    public:
                   __fastcall TMultiImageScroller(TComponent* Owner);
                   __fastcall ~TMultiImageScroller(void);
      virtual void __fastcall LoadFromFileList(TStringList* Names, Boolean Add);
      virtual void __fastcall Clear(void);
      virtual void __fastcall ArrangeImage(void);
    __published:
      __property int Rows={read=Row,write=SetRow,nodefault} ;
      __property int Cols={read=Column,write=SetColumn,nodefault} ;
    };
    

    Im CTor erzeugste 'ne leere TList fuer *FImagePanelList
    Im DTor deleten.

    in LoadFromFileList erzeugste fuer jeden Dateinamen der uebergebenen Liste
    ein ImagePanel (aus Teil 1) und addest das in die Liste

    Groesse des ImagePanel aus Boxgroesse, Row und Column berechnen.

    In Parameter Names uebergibst Du ne StringList mit allen dateinamen

    Falls Add=false ist wird FImagePanelList geleert vor dem Laden der Bilder - Alle ImagePanels aus der Liste deleten und Listeneintrag loeschen!.

    PS: Probier's mal 😉



  • Hi,
    danke nochmal für die Hilfe. Ich habe es jetzt so gemacht das ich für jedes Bild ein Pannel habe. Anstelle IP->... hab ich jetzt in einer Schleife IP[i]->... So muss ich auch keine ImageList benutzen. D.h. ich komme ohne die abgeleitete Klasse davon 😉

    MfG
    Basti



  • Siehste, 's geht doch! 😉

    Aber ne Kompo ist besser zu handhaben!

    Kannst ja mal folgendes probieren:

    //Ist ne Kompo / Klasse als ScrollBox fuer die TImagePanels!
    //Kannste mit dem Header zu der anderen (Teil 1) hinzufuegen!

    static inline void ValidCtrCheck(TMultiImageScroller *)
    { new TMultiImageScroller(NULL);
    }
    //---------------------------------------------------------------------------
    __fastcall TMultiImageScroller::TMultiImageScroller(TComponent* Owner)
            : TScrollBox(Owner)
    { FImagePanelList=new TList;
      Files=NULL;
      Column=2;
      Row=1;
    }
    //---------------------------------------------------------------------------
    __fastcall TMultiImageScroller::~TMultiImageScroller(void)
    { if (Files!=NULL)
        delete Files;
      delete FImagePanelList;
    }
    //---------------------------------------------------------------------------
    void __fastcall TMultiImageScroller::LoadFromFileList(TStringList* Names, Boolean Add)
    { int i;
      int j=0;
      int PanelWidth;
      int PanelHeight;
      TImagePanel* ImagePanel;
      if (Files!=NULL)
      { if (!Add)
        { delete Files;
          Files=new TStringList;
        }
      }
      else
      { Files=new TStringList;
      }
      j=Files->Count;
      for (i=0;i<Names->Count;i++)
        if (Files->IndexOf(Names->Strings[i])<0)
          Files->Add(Names->Strings[i]);
      if (j>0)
      { PanelWidth=((TImagePanel*) (FImagePanelList->Items[0]))->Width;
        PanelHeight=((TImagePanel*) (FImagePanelList->Items[0]))->Height;
      }
      else
      { PanelWidth=(ClientWidth) / Column;
        PanelHeight=(ClientHeight) / Row;
      }
      for (i=j;i<Files->Count;i++)
      { if (i<FImagePanelList->Count)
        { ImagePanel=(TImagePanel*) (FImagePanelList->Items[i]);
        }
        else
        { ImagePanel=new TImagePanel(this);
          FImagePanelList->Add(ImagePanel);
        }
        ImagePanel ->Enabled=false;
        ImagePanel->Width=PanelWidth;
        ImagePanel->Height=PanelHeight;
        ImagePanel->Left=(i%Column) * PanelWidth-HorzScrollBar->Position;
        ImagePanel->Top=(i / Column) * PanelHeight-VertScrollBar->Position;
        ImagePanel->ShowHint=true;
        ImagePanel->Hint=Files->Strings[i];
        ImagePanel->Parent=this;
      }
      while(FImagePanelList->Count>Files->Count)
      { delete (TImagePanel*) (FImagePanelList->Items[FImagePanelList->Count-1]);
        FImagePanelList->Delete(FImagePanelList->Count-1);
      }
      VertScrollBar->Smooth=false;
      VertScrollBar->Increment=(short) PanelHeight;
      HorzScrollBar->Smooth=false;
      HorzScrollBar->Increment=(short) PanelWidth;
      for (i=j;i<Files->Count;i++)
      { ImagePanel=(TImagePanel*) (FImagePanelList->Items[i]);
        ImagePanel->LoadFromFile(Files->Strings[i]);
        ImagePanel->Refresh();
      }
    }
    //---------------------------------------------------------------------------
    void __fastcall TMultiImageScroller::Clear(void)
    { if (FImagePanelList->Count>0)
        Files->Clear();
      while (FImagePanelList->Count>0)
      { delete (TImagePanel*) (FImagePanelList->Items[0]);
        FImagePanelList->Delete(0);
      }
    }
    //---------------------------------------------------------------------------
    void __fastcall TMultiImageScroller::SetRow(int Rows)
    { Row=Rows;
    }
    //---------------------------------------------------------------------------
    void __fastcall TMultiImageScroller::SetColumn(int Cols)
    { Column=Cols;
    }
    //---------------------------------------------------------------------------
    void __fastcall TMultiImageScroller::ArrangeImage(void)
    { int i;
      int PanelWidth;
      int PanelHeight;
      TImagePanel* ImagePanel;
      PanelWidth=(ClientWidth) / Column;
      PanelHeight=(ClientHeight) / Row;
      for (i=0;i<FImagePanelList->Count;i++)
      {
        ImagePanel=(TImagePanel*) (FImagePanelList->Items[i]);
        ImagePanel->Width=PanelWidth;
        ImagePanel->Height=PanelHeight;
        ImagePanel->Left=(i%Column) * PanelWidth-HorzScrollBar->Position;
        ImagePanel->Top=(i / Column) * PanelHeight-VertScrollBar->Position;
        ImagePanel->LoadFromFile(ImagePanel->FName);
      }
    }
    //---------------------------------------------------------------------------
    


  • Und wie mach ich das jetzt wenn ich beim klick auf eines der vielen dargestllten Bilder eine MessageBox anzeigen will mit einer Bildspezifischen Information? Ich hab ja nirgends ein onKlick Ereignis?

    MfG
    Basti


Anmelden zum Antworten