Einzelnen Beitrag anzeigen

Benutzerbild von Jazzman_Marburg
Jazzman_Marburg

Registriert seit: 2. Aug 2004
359 Beiträge
 
#1

Bitmap ==> Image kopieren, Seitenverhältnis beachten

  Alt 10. Dez 2009, 20:18
Moin, Moin.

Ich habe das Problem, ein (OffScreen) Bitmap (egal welcher Größe) in ein Image (sichtbar auf der Form) zu kopieren, das Seitenverhätlnis des Bitmaps sollte aber beibehalten werden. "Stretch" macht dies ja genau nicht. Dabei bin ich auf eine Lösung von "efg's Computer Lab" (efg) gestoßen, die aber scheint einen Bug zu haben -- vielleicht ist von Euch ja jemanden sofort klar, was das Problem ist.
Hier mein Szenario:
Die TImage Komponente auf der Form ist 128x305 Pixel groß. Ist nun das übergebene (und mit efg's konvertierte) Bitmap 200x200 Pixel groß, wird es prima verkleintert auf dem Image gezeigt (korrektes Seitenverhältnis). Das ist auch schön der Fall, falls das Bitmap kleiner ist: Dann wird es korrekt vergrößert.
Sobald aber eine Seite des Bitmaps die magische Größe von 255 überschreitet, wird nur ein Teil des Bitmaps auf dem Image gezeichnet. (Genauer: Das umgebende Rechteck ist einfach nicht sichtbar!)

Hier die Konvertierungsroutine von efg:

Delphi-Quellcode:
{ Display Bitmap in Image.  Keep the TBitmap as large as possible in the TImage}
{ while maintaining the correct aspect ratio. ---------------------------------}

PROCEDURE TMeine_Frm.DisplayBitmap(const FromBitmap: TBitmap; const ToImage: TImage);
VAR
  Half : INTEGER;
  Height : INTEGER;
  NewBitmap : TBitmap;
  TargetArea: TRect;
  Width : INTEGER;

BEGIN
  NewBitmap := TBitmap.Create;
  TRY
    NewBitmap.Width := ToImage.Width ;
    NewBitmap.Height := ToImage.Height;
    NewBitmap.PixelFormat := pf24bit;

    //NewBitmap.Canvas.Brush := ShapeFill.Brush; // ???
    NewBitmap.Canvas.FillRect(NewBitmap.Canvas.ClipRect);
    // "equality" (=) case can go either way in this comparison

    IF FromBitmap.Width / FromBitmap.Height < ToImage.Width / ToImage.Height
    THEN BEGIN
      // Stretch Height to match.
      TargetArea.Top := 0;
      TargetArea.Bottom := NewBitmap.Height;
      // Adjust and center Width.
      Width := MulDiv(NewBitmap.Height, FromBitmap.Width, FromBitmap.Height);
      Half := (NewBitmap.Width - Width) DIV 2;
      TargetArea.Left := Half;
      TargetArea.Right := (TargetArea.Left + Width) ;
    END
    ELSE BEGIN
      // Stretch Width to match.
      TargetArea.Left := 0;
      TargetArea.Right := NewBitmap.Width;
      // Adjust and center Height.
      Height := MulDiv(NewBitmap.Width, FromBitmap.Height, FromBitmap.Width);
      Half := (NewBitmap.Height - Height) DIV 2;
      TargetArea.Top := Half;
      TargetArea.Bottom := (TargetArea.Top + Height);
    END;

    NewBitmap.Canvas.StretchDraw(TargetArea, FromBitmap);
    ToImage.Picture.Graphic := NewBitmap;

  FINALLY
    NewBitmap.Free
  END;

END;
In der Routine wird das FromBitmap Seitenverhältnis-Gerecht in das ToImage kopiert. NewBitmap ist, wie man sehen kann eine temoräres Bitmap.

Hat jemand eine Erklärung dafür, warum die Routine schlapp macht, wenn entweder FromBitmap.Height oder FromBitmap.Width > 255 ist?

Vielen Dank für jedweden Hinweis

Gruß
Jazzman
--- Delphi XE Starter, Windows 8 ---
  Mit Zitat antworten Zitat