Hallo zusammen,
ich benutze folgende Prozedur, um Bitmaps zu drehen und zu zoomen (und danach auf einen tImage abzubilden):
Delphi-Quellcode:
procedure TdlgMain.RotateImage;
var
svMode: Integer;
vMatrix: tagXFORM;
svMatrix: tagXFORM;
vSine: Extended;
vCosine: Extended;
vAngle: Double;
vOffsetX: Integer;
vOffsetY: Integer;
Z: Double;
begin
bmEasel.Height := bmCustom.Height;
bmEasel.Width := bmCustom.Width;
bmEasel.Canvas.Brush.Style := bsSolid;
bmEasel.Canvas.Brush.Color := clWhite;
bmEasel.Canvas.Fillrect(bmEasel.Canvas.ClipRect);
{......................................................................}
vAngle := sbAngle.Position;
vOffsetX := sbOffsetX1.Position;
vOffsetY := sbOffsetY1.Position;
Z := sbZoom1.Position / 100;
{......................................................................}
svMode := SetGraphicsMode(bmEasel.Canvas.Handle, GM_ADVANCED);
if (svMode = GM_ADVANCED) then
GetWorldTransform(bmEasel.Canvas.Handle, svMatrix);
{......................................................................}
FillChar (vMatrix, SizeOf(vMatrix), 0);
vMatrix.em11 := 1.0;
vMatrix.em22 := 1.0;
vMatrix.eDx := -(vOffsetX + bmEasel.Width / 2);
vMatrix.eDy := -(vOffsetY + bmEasel.Height / 2);
SetWorldTransform(bmEasel.Canvas.Handle, vMatrix);
{......................................................................}
SinCos (vAngle * Pi / 180, vSine, vCosine);
FillChar (vMatrix, SizeOf(vMatrix), 0);
if Z = 1 then begin
vMatrix.em11 := vCosine;
vMatrix.em12 := vSine;
vMatrix.em21 := -vSine;
vMatrix.em22 := vCosine;
end
else begin
vMatrix.em11 := Z * Cos(0.0174532925199433 * vAngle);
vMatrix.em12 := Z * Sin(0.0174532925199433 * vAngle);
vMatrix.em21 := -Z * Sin(0.0174532925199433 * vAngle);
vMatrix.em22 := Z * Cos(0.0174532925199433 * vAngle);
end;
ModifyWorldTransform(bmEasel.Canvas.Handle, vMatrix, MWT_RIGHTMULTIPLY);
{......................................................................}
FillChar (vMatrix, SizeOf(vMatrix), 0);
vMatrix.em11 := 1.0;
vMatrix.em22 := 1.0;
vMatrix.eDx := (vOffsetX + bmEasel.Width / 2);
vMatrix.eDy := (vOffsetY + bmEasel.Height / 2);
ModifyWorldTransform(bmEasel.Canvas.Handle, vMatrix, MWT_RIGHTMULTIPLY);
{......................................................................}
bmEasel.Canvas.Draw(vOffsetX, vOffsetY, bmCustom);
{......................................................................}
if (svMode = GM_ADVANCED) then
SetWorldTransform(bmEasel.Canvas.Handle, svMatrix)
else SetGraphicsMode(bmEasel.Canvas.Handle, svMode);
{......................................................................}
FitBitmap(bmEasel, iEaselShow);
end;
procedure FitBitmap(Source: tBitmap; Dest: tImage);
var
R: Double;
begin
if Dest.Height < Dest.Width then R := Dest.Height / Source.Height
else R := Dest.Width / Source.Width;
try
ScaleImage(Source, Dest.Picture.Bitmap, R);
except
end;
end;
Den wesentlichen Teil der Prozedur habe ich hier
http://www.delphipraxis.net/526724-post9.html in der
DP gefunden, die Ergänzung fürs Zoomen hier
http://www.delphipraxis.net/1295365-post10.html.
Das Pixelformat der beiden Bitmaps ist pf24bit (explizit gesetzt), das Ganze läuft unter Windows 7 64 und XE 6.
Was ist nun mein Problem: Rotieren und Zoomen funktionieren schnell und problemlos bis zu einer Bitmap-Größe von unter 9 Mio Pixel. Mit 9 Mio Pixel wird es erratisch (klappt mal (dann sehr lange Laufzeit) klappt mal nicht), bei noch größeren Biptmaps passiert überhaupt nichts. D. h., dass auch kein Fehler ausgeworfen wird, auch ist das Ergebnis der verwendeten
GDI-Funktion immer True.
Ich habe auch nach längeren Suchen nichts zu diesem Problem oder einer
GDI Größenbeschränkungen gefunden.
Hat einer von euch eine Idee?