AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

GDI Größenbeschränkung?

Ein Thema von striderx · begonnen am 3. Mär 2016 · letzter Beitrag vom 3. Apr 2016
Antwort Antwort
striderx

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

GDI Größenbeschränkung?

  Alt 3. Mär 2016, 18: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
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#2

AW: GDI Größenbeschränkung?

  Alt 7. Mär 2016, 01:17
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?
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
striderx

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

AW: GDI Größenbeschränkung?

  Alt 7. Mär 2016, 09:32
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.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: GDI Größenbeschränkung?

  Alt 7. Mär 2016, 10:28
Wer so etwas schreibt
Delphi-Quellcode:
  try
    MachIrgendwas();
  except
  end;
und sich dann wundert, wenn es mal kein Ergebnis gibt, gehört IMHO geteert und gefedert

Also weg mit dem unsinnigen und blinden Wegfangen der Exceptions und schau, was der Rechner dir zu sagen hat (und ob).
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#5

AW: GDI Größenbeschränkung?

  Alt 7. Mär 2016, 11:12
Ist das hier von der Logik her wirklich so gewollt, dass die Matrix nur dann retrieved wird, wenn der ALTE GraphicsMode GM_ADVANCED war?
Delphi-Quellcode:
svMode := SetGraphicsMode(bmEasel.Canvas.Handle, GM_ADVANCED);
if (svMode = GM_ADVANCED) then
  GetWorldTransform(bmEasel.Canvas.Handle, svMatrix);
Denn laut MSDN liefert dir MSDN-Library durchsuchenSetGraphicsMode als Result:
Zitat:
If the function succeeds, the return value is the old graphics mode.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
striderx

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

AW: GDI Größenbeschränkung?

  Alt 7. Mär 2016, 17:13
@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

SetGraphicsMode(bmEasel.Canvas.Handle, svMode); nicht wieder gesetzt wird, erfolgt keine Drehung, auch bei kleineren Bitmaps nicht.


@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"

Geändert von striderx ( 7. Mär 2016 um 17:32 Uhr)
  Mit Zitat antworten Zitat
striderx

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

AW: GDI Größenbeschränkung?

  Alt 3. Apr 2016, 11:43
Vielleicht interssieret es ja jemanden:

Der Fehler tritt unter Windows 7 auf - nicht aber unter Windows 10.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:22 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz