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