TImage anpassen



  • jo habe ich auch soeben bemerkt.
    Kannst du mir vielleicht auch sagen wo ich diese Proportional-Variable finden kann. (Tipp von Morris Szyslak)
    Glaube fast, dass mir sowas lieber wäre.
    Also dass ich immer dieselbe Größe habe und dass das Bild dann proportional hineinverkleinert bzw. vergrößert wird. Also nicht wie bei der Option Stretch verzerrt wird.

    Kiki



  • Hallo

    zumindestens im Builder 5 gibts das (noch) nicht.

    bis bald
    akari



  • ah ok. Trotzdem danke für die Info.
    Und danke für die Hilfe mit der ScollBox.

    THX Kiki



  • Versuch mal das hier:

    Image1 und ScrollBox1 sollten klar sein. BitmapShow ist das Bild, das in dem Image dargestellt werden soll (TBitmap). Sollte sich auch ohne Probleme auf TJPEGImage anpassen lassen.

    TRect ar;
    	double factor_x;
    	double factor_y;
    	double factor;
    
    	factor_x = (double) BitmapShow->Width / (double) ScrollBox1->ClientWidth;
    	factor_y = (double) BitmapShow->Height / (double) ScrollBox1->ClientHeight;
    	factor = factor_x > factor_y ? factor_x : factor_y;
    
    	ar.top = 0;
    	ar.left = 0;
    	ar.right = BitmapShow->Width / factor;
    	ar.bottom = BitmapShow->Height / factor;
    
    	// Darstellung des Bitmaps
    	Image1->Picture->Assign(NULL);
    	Image1->Top = 0;
    	Image1->Left = 0;
    	Image1->Width = ar.right;
    	Image1->Height = ar.bottom;
    	Image1->Proportional = false;
    
    	Image1->Canvas->StretchDraw(ar, BitmapShow);
    
    	if (Image1->Height < ScrollBox1->ClientHeight) // vertikal zentrieren?
    		Image1->Top = (ScrollBox1->ClientHeight - Image1->Height) / 2;
    	else
    		Image1->Top = 0;
    	if (Image1->Width < ScrollBox1->ClientWidth)	// hozizontal zentrieren?
    		Image1->Left = (ScrollBox1->ClientWidth - Image1->Width) / 2;
    	else
    		Image1->Left = 0;
    


  • Proportional ist eine Eigenschaft von TImage im BCB6.



  • Ob diese Eigenschaft soviel nützt? Damit kann man z.Bsp. ein Bild nicht vergrößern. Joes Methode scheint mir da geeigneter.



  • hm...

    Image->Proportional=true;
    Image->Stretch=true;
    Image->Align=alClient;

    Vergrößert und verkleinert bei mir ganz gut. Wenn ich Joe_M.s Code richtig verstehe, tut er so ziemlich das gleiche.



  • Ja ist es. So wie ich es verstanden hab, geht es hier um den BCB 5, da gab es wohl die Proportional-Eigenschaft noch nicht.



  • Du verwendest Proportional doch auch. 🙂
    Das kannst du natürlich auch weglassen.
    Meine Aussage bezog sich auf folgenden Text aus der BCB6-Hilfe

    Setzen Sie Proportional auf true, damit die Grafik vollständig im TImage-Steuerelement angezeigt wird und keine Verzerrungen wie bei der Eigenschaft Stretch vorkommen. Grafiken, die zu groß für das Steuerelement sind, werden solange skaliert (wobei das Bildseitenverhältnis beibehalten wird), bis sie in dem Steuerelement vollständig angezeigt werden können. Zu kleine Grafiken werden in der normalen Größe dargestellt. Proportional kann Grafiken verkelinern, aber nicht vergrößern.



  • Ups, ja richtig... Hätte ich rauslöschen sollen. Das Codeschnipsel stammt aus einer Routine, mit der man die Bilder, unter anderem, auch ein- und auszoomen kann.



  • Danke für eure Antworten. War seit Mi im verlängerten WE-Urlaub und kann deshalb erst jetzt antworten. Also das Code-Beispiel von Joe_M. find ich richtig gut. Hab da aber leider noch ein kleines Problem:

    BitmapShow->Width erkennt mein Complier net. Aber wenn mich nicht alles täuscht sind das die Daten des Bilds selber. Deshlab habe ich das einfach durch: Image->Picture->Graphic->Height ersetzt.
    Dadurch hab ich dann auch keine Fehler mehr.
    Problem ist dann nur, dass ich ein weißes Bild habe. die Größe passt er mir aber immer an und in der StatusZeile bekomme ich auch den Dateinamen angezeigt. Ich habs auch schonmal mit Image->Refresh() versucht, hat aber leider auch nicht geholfen.

    Hier mal mein Code:

    void TMainProg::Bild_laden(AnsiString bild)
    {
      Image->Picture->LoadFromFile(bild);
      StatusBar->Panels->Items[0]->Text="Aktuell angezeigtes Bild: " + bild.SubString(bild.LastDelimiter("\\")+1,bild.Length());
      //Bild anpassen
      TRect ar;
        double factor_x;
        double factor_y;
        double factor;
    
        factor_x = (double) Image->Picture->Graphic->Width / (double) ScrollBox1->ClientWidth;
        factor_y = (double) Image->Picture->Graphic->Height / (double) ScrollBox1->ClientHeight;
        factor = factor_x > factor_y ? factor_x : factor_y;
    
        ar.top = 0;
        ar.left = 0;
        ar.right = Image->Picture->Graphic->Width / factor;
        ar.bottom = Image->Picture->Graphic->Height / factor;
    
        // Darstellung des Bitmaps
        Image->Picture->Assign(NULL);
        Image->Top = 0;
        Image->Left = 0;
        Image->Width = ar.right;
        Image->Height = ar.bottom;
    
        Image->Canvas->StretchDraw(ar, Image->Picture->Graphic);
    
        if (Image->Height < ScrollBox1->ClientHeight) // vertikal zentrieren?
            Image->Top = (ScrollBox1->ClientHeight - Image->Height) / 2;
        else
            Image->Top = 0;
        if (Image->Width < ScrollBox1->ClientWidth)    // hozizontal zentrieren?
            Image->Left = (ScrollBox1->ClientWidth - Image->Width) / 2;
        else
            Image->Left = 0;
       Image->Refresh();
    }
    

    Hoffe ihr könnt mir nochmal helfen.

    Kiki



  • Das liegt an der Image->Picture->Assign(NULL). Dort wird das 'alte' Bild gelöscht, bevor das neue eingefügt wird. Laß die Zeile einfach mal raus.



  • Danke für den Tipp, funktioniert aber leider nicht. Wenn ich die Zeile ausblende bekomme ich folgenden Fehler:...im Projekt ist folgende Exception der Klasse EInvalidOperation aufgetreten. "Ein Bild kann nur geändert werden, wenn es ein Bitmap enthält!"...

    Heißt das etwa, dass dieser Code nur für *.bmp funktioniert?



  • Nein nicht unbedingt. 😉 Kannst auch JPEGs oder GIFs nehmen, allerdings habe ich es bei mir so gelöst, dass die Bilder, nach dem Einlesen einem TBitmap zugewiesen werden. Sprich das Bild in ein TJPEGImage einlesen, dieses dann einem TBitmap 'assignen'.



  • Aha, ich glaube fast, dass das für mich noch zu hoch ist. Werde mich gleich mal schlau machen, wie ich das machen kann.
    Kannst mir vielleicht auch ein Code-Bsp geben. 😕

    THX

    EDIT:
    Geht das ungefähr so: (hab ich in der BSB Hilfe gefunden)

    TJPEGImage *jp=new TJPEGImage();
    try
    {
    jp->Assign(Image->Picture->Bitmap);
    }
    __finally
    {
    delete jp;
    }



  • Das hängt mehr davon ab, in welchem Format die Bilder auf der Festplatte gespeichert sind. Für diese Formate gibt es Importfilter (eben zum Beispiel TJPEGImage). Damit liest man die Datei ein. Zur Verarbeitung verwendet man Bitmaps, weil dies das native Fornmat unter Windows ist.

    In welchem Format liegen die Bilder bei Dir vor?



  • Sind in der Regel *.jpg bzw. *.jpeg

    Edit:
    Mein Code sieht jetzt so aus. Scheint auch zu funktionieren, tut es aber leider nicht 100%ig. Ich habe ein Bild mit Paint erstellt und als *.jpg gespeichert. In diesem Bild habe ich auch Text eingefügt. Wenn ich dieses Bild lade, gibt es einige Fehler. Die Schrift ist glaub ein bissle verzert und nicht vollständig. Wenn ich das Bild lade die größe manuell (habe im Explorer die Größe und Breite nachgeschaut und im Image->Widht bzw. ->Height manuell eingegeben)anpasse, dann wird das Bild richtig angezeigt.

    void TMainProg::Bild_laden(AnsiString bild)
    {
      Image->Picture->LoadFromFile(bild);
      StatusBar->Panels->Items[0]->Text="Aktuell angezeigtes Bild: " + bild.SubString(bild.LastDelimiter("\\")+1,bild.Length());
      Graphics::TBitmap *bmp = new Graphics::TBitmap();
      try
      {
        bmp->Assign(Image->Picture->Graphic);
      }
      catch(...)
      {
    
      }
      //Bild anpassen
      TRect ar;
        double factor_x;
        double factor_y;
        double factor;
    
        factor_x = (double) bmp->Width / (double) ScrollBox1->ClientWidth;
        factor_y = (double) bmp->Height / (double) ScrollBox1->ClientHeight;
        factor = factor_x > factor_y ? factor_x : factor_y;
    
        ar.top = 0;
        ar.left = 0;
        ar.right = bmp->Width / factor;
        ar.bottom = bmp->Height / factor;
        // Darstellung des Bitmaps
        Image->Picture->Assign(NULL);
        Image->Top = 0;
        Image->Left = 0;
        Image->Width = ar.right;
        Image->Height = ar.bottom;
    
        Image->Canvas->StretchDraw(ar, bmp);
    
        if (Image->Height < ScrollBox1->ClientHeight) // vertikal zentrieren?
            Image->Top = (ScrollBox1->ClientHeight - Image->Height) / 2;
        else
            Image->Top = 0;
        if (Image->Width < ScrollBox1->ClientWidth)    // hozizontal zentrieren?
            Image->Left = (ScrollBox1->ClientWidth - Image->Width) / 2;
        else
            Image->Left = 0;
        delete bmp;
    }
    

    Edit2:
    Es handelt sich echt nur um minimale Fehler in der Darstellung des Textes.
    Kann dieser Fehler eventuell durch dich Division kommen. Hierbei entsteht ja eine Kommzahl. Und am Ende wird ja aus der Kommazahl (z.B. 736,6) wieder ein Integer erstehlt. Ich hab jetzt grad überlegt, ob eventuell bei Image->Width aufgerundet und bei Image->Heigth abgerundet wird, und dass dieser eine Pixel dann das Bild so leicht verzerrt, dass es auffällt.
    Was haltet ihr davon??? Holzweg 👎 oder gute Idee 👍 ??


Anmelden zum Antworten