Einzelnen Beitrag anzeigen

striderx

Registriert seit: 11. Feb 2007
Ort: Bergisch Gladbach
206 Beiträge
 
Delphi 10.4 Sydney
 
#1

GDI Größenbeschränkung?

  Alt 3. Mär 2016, 17:05
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?
  Mit Zitat antworten Zitat