![]() |
GDI Größenbeschränkung?
Hallo zusammen,
ich benutze folgende Prozedur, um Bitmaps zu drehen und zu zoomen (und danach auf einen tImage abzubilden):
Delphi-Quellcode:
Den wesentlichen Teil der Prozedur habe ich hier
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; ![]() ![]() 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? |
AW: GDI Größenbeschränkung?
Bitmaps sind GDI-seitig auf 65536x65536 Pixel beschränkt, aber das ist ja noch weit weit über deiner Größe von quasi 3000x3000. (Diese Begrenzung habe ich irgendwann mal beim Stöbern in den Seiten von MS gefunden, war bisher aber nicht in der Lage dazu dies wiederzufinden :()
Mit knapp 35MB kommst du eigentlich auch noch lange nicht an irgendwelche brenzlige Speichergrenzen. Ich sehe auch nichts was direkt ins Auge stechen würde im Code. Gibt der Taskmanager evtl. etwas mehr Aufschluss? Explodierender Speicherbedarf, oder plötzlich Unmengen an verbrauchten Handles oder sowas? Was sagt die CPU dazu wenn es gerade mal länger dauert? |
AW: GDI Größenbeschränkung?
Wenn es länger dauert, geht die CPU-Last um 25 - 30% hoch, die Anzahl der Handles verändert sich nicht wesentlich, der Speicherbedarf scheint mir normal zu sein. Wenn es nicht längere dauert, ist die Prozedur ratz fatz durchlaufen - nur ohne Ergebnis halt.
Was mir bei den Langläufern auffällt: Im Task-Manager ist das Programm dann der CPU 25 zugeordnet, was bei einer Vier-Kern-CPU natürlich verwundert. Das könnte aber daran liegen, dass das Programm während der Aussführung der Prozedur keine Rückmeldung gibt. |
AW: GDI Größenbeschränkung?
Wer so etwas schreibt
Delphi-Quellcode:
und sich dann wundert, wenn es mal kein Ergebnis gibt, gehört IMHO geteert und gefedert :stupid:
try
MachIrgendwas(); except end; Also weg mit dem unsinnigen und blinden Wegfangen der Exceptions und schau, was der Rechner dir zu sagen hat (und ob). |
AW: GDI Größenbeschränkung?
Ist das hier von der Logik her wirklich so gewollt, dass die Matrix nur dann retrieved wird, wenn der ALTE GraphicsMode
Delphi-Quellcode:
war?
GM_ADVANCED
Delphi-Quellcode:
Denn laut MSDN liefert dir
svMode := SetGraphicsMode(bmEasel.Canvas.Handle, GM_ADVANCED);
if (svMode = GM_ADVANCED) then GetWorldTransform(bmEasel.Canvas.Handle, svMatrix); ![]() Zitat:
|
AW: GDI Größenbeschränkung?
@Sir Rufo
Da hab ich ja Glück gehabt, dass du micht nicht noch anzünden willst. ;-) Aber ernsthaft: Da stand natürlich vorher etwas drin, ich habe nur vergessen, den try Block auch noch zu löschen. Ein Fehler ist an dieser Stelle übrigens nicht ausgeworfen worden. @Zacherl Der ursprüngliche Autor (s. Link in meinem Eingangspost) hat das so kommentiert, dass hier der aktuelle Grafik-Modus zwischengespeichert und dann nach Abschluss der Operation wieder restauriert wird. Ich habe jetzt mal nachgesehen: Bei mir ist der Graphic-Modus nie GM_Advanced. Wenn der Modus aber nicht ausgelesen und später mit
Delphi-Quellcode:
nicht wieder gesetzt wird, erfolgt keine Drehung, auch bei kleineren Bitmaps nicht.
SetGraphicsMode(bmEasel.Canvas.Handle, svMode);
@alle: Es wäre natürlich toll, wenn das mal jemand bei sich laufen lassen würde, um zu schauen, ob das Problem auch woanders auftritt. "now we are still confused but we are confused on a higher level" |
AW: GDI Größenbeschränkung?
Vielleicht interssieret es ja jemanden:
Der Fehler tritt unter Windows 7 auf - nicht aber unter Windows 10. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:09 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz