AGB  ·  Datenschutz  ·  Impressum  







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

Grenzen von PlgBlt

Ein Thema von Schwedenbitter · begonnen am 5. Mai 2009 · letzter Beitrag vom 22. Nov 2010
Antwort Antwort
Schwedenbitter

Registriert seit: 22. Mär 2003
Ort: Finsterwalde
622 Beiträge
 
Turbo Delphi für Win32
 
#1

AW: Re: Grenzen von PlgBlt

  Alt 22. Nov 2010, 14:02
Hallo,

mit der Zeit werde auch ich schlauer und habe somit gelernt, wie man DLL-Funktionen einbinden kann . Ich habe jetzt in den Implementations-Teil meiner "Dreh-Unit" folgendes geschrieben:
Delphi-Quellcode:
Const
  Status = (Ok, GenericError, InvalidParameter, OutOfMemory,
ObjectBusy, InsufficientBuffer, NotImplemented, Win32Error, WrongState, Aborted, FileNotFound, ValueOverflow, AccessDenied, UnknownImageFormat, FontFamilyNotFound, FontStyleNotFound, NotTrueTypeFont, UnsupportedGdiplusVersion, GdiplusNotInitialized, PropertyNotFound, PropertyNotSupported);
  TStatus = Status;
  GpStatus = TStatus;

Function GdipImageRotateFlip(Image: Pointer;
   rfType: ROTATEFLIPTYPE): GPSTATUS; Stdcall; External 'gdiplus.dll';
Die Deklaration von RotateFlipType habe ich jetzt mal außen vor gelassen. Die Deklaration von GPStatus ist nicht auf meinem Mist gewachsen, sonder ich habe sie einfach aus der Unit GDIPAPI.pas von progdigy übernommen.
Und so sollte das dann von mir aufgerufen werden:
Delphi-Quellcode:
Procedure TMainForm.BtnRotateClick(Sender: TObject);
Var
  Stat      : GPStatus;
  tmp      : HBitmap;
Begin
  tmp:=Image1.Picture.Bitmap.Handle;
  Stat:=GdipImageRotateFlip(@tmp, Rotate90FlipNone);
  ShowMessage(StatusText[Stat]);
End;
TImage.Picture.Bitmap.Handle ist doch vom Typ HBITMAP. Ist das eine anderes HBITMAP als es GDI+ benutzt?
Denn ich bekomme immer die Statusmeldung "ObjectBusy" zurück. Erwartet hatte ich eigentlich "GdiplusNotInitialized", weil ich genau das nicht getan habe; Initialisieren.

Könnte mir bei der Gelegenheit bitte mal jemand ein Beispiel posten, wie ich mit den Funktionen "GdipCreateBitmapFromHBITMAP" bzw. "GdipCreateHBITMAPFromBitmap" ein TBitmap aus Delphi in ein GDI+-konformes HBITMAP umwandeln kann und umgekehrt?

Mehr als das und "GdipImageRotateFlip" brauche ich vermutlich wirklich nicht, so dass mein Code übersichtlich und mein Programm schön klein bliebe!

Bitte, bitte, Alex
Alex Winzer
  Mit Zitat antworten Zitat
Schwedenbitter

Registriert seit: 22. Mär 2003
Ort: Finsterwalde
622 Beiträge
 
Turbo Delphi für Win32
 
#2

AW: Re: Grenzen von PlgBlt

  Alt 22. Nov 2010, 17:23
Der "falsche" Fehlercode kommt wohl daher, dass ich GDI+ nicht initialisiert hatte. Jetzt klappt es mit dem Erzeugen durch GdipCreateBitmapFromHBITMAP() . Der Status passt und der Pointer auf das Image ist nicht mehr nil .

Allerdings erhalt ich nun beim Aufruf von GdipImageRotateFlip als Status-Rückmeldung InvalidParameter wobei folgendes definiert ist:
Delphi-Quellcode:
Type
  RotateFlipType= (RotateNoneFlipNone = 0,
                   Rotate90FlipNone = 1,
                   Rotate180FlipNone = 2,
                   Rotate270FlipNone = 3,
                   RotateNoneFlipX = 4,
                   Rotate90FlipX = 5,
                   Rotate180FlipX = 6,
                   Rotate270FlipX = 7,
                   RotateNoneFlipY = Rotate180FlipX,
                   Rotate90FlipY = Rotate270FlipX,
                   Rotate180FlipY = RotateNoneFlipX,
                   Rotate270FlipY = Rotate90FlipX,
                   RotateNoneFlipXY = Rotate180FlipNone,
                   Rotate90FlipXY = Rotate270FlipNone,
                   Rotate180FlipXY = RotateNoneFlipNone,
                   Rotate270FlipXY = Rotate90FlipNone);
  Status = (Ok, GenericError, InvalidParameter, OutOfMemory,
                   ObjectBusy, InsufficientBuffer, NotImplemented,
                   Win32Error, WrongState, Aborted, FileNotFound,
                   ValueOverflow, AccessDenied, UnknownImageFormat,
                   FontFamilyNotFound, FontStyleNotFound,
                   NotTrueTypeFont, UnsupportedGdiplusVersion,
                   GdiplusNotInitialized, PropertyNotFound,
                   PropertyNotSupported);
  TStatus = Status;
  GpStatus = TStatus;
Auch das stammt nicht von mir, sondern ist ein Ausschnitt aus der von mir bereits zitierten Unit.

Was mache ich denn nun wieder falsch?

Mein Ziel ist es nachwievor, einfach nur ein TBitmap herzunehmen, in ein GDI+Bild umzuwandeln, dieses zu drehen und dann wieder in ein TBitmap zurückzuwandeln.
Alex Winzer
  Mit Zitat antworten Zitat
Schwedenbitter

Registriert seit: 22. Mär 2003
Ort: Finsterwalde
622 Beiträge
 
Turbo Delphi für Win32
 
#3

AW: Re: Grenzen von PlgBlt

  Alt 22. Nov 2010, 23:15
Ich antworte nun mal selbst:

ich habe es mit den Funktionen hinbekommen. Offenbar gelten die Grenzen von PlgBlt() bedauerlicher Weise auch für GdipImageRotateFlip() . Die Ursache für die Speicherzugriffsverletzungen und sonstigen Fehlermeldungen war schlicht die, dass mein Test-Bild zu groß ist. Benutze ich ein kleineres Bild, dann klappt das ganze prima.
Es gibt bloß ein Speicherleck, dass ich mit FastMM nicht eingrenzen kann. Bei jedem Drehen, braucht das Programm mehr Speicher und FastMM zeigt beim Beenden rein garnichts an. Ich habe sogar schon Speicherlecks provoziert, die gezeigt werden. Aber der andere Verbrauch ist unergründlich.

Da ich also die API von Windows wohl vergessen kann, muss ich mir jetzt überlegen, wie ich den Code von Blup so aufbohre, dass er auch für Bilder mit pf24bit funktioniert.

Gruß, Alex
Alex Winzer
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#4

AW: Grenzen von PlgBlt

  Alt 22. Nov 2010, 23:33
Ich nutze GID+ sehr ausgiebig, allerdings mit Streams und Painroutinen, falls Du schnelle und einfache Canvasroutinen brauchen solltest, kann du ja hie mal bohren und erweitern:
Delphi-Quellcode:
unit ExCanvasTools;
// 20100915 by Thomas Wassermann
interface
uses
  Windows, SysUtils, Classes, Graphics;

  Function Grad2Rad(w:Double):Double;
  Procedure PaintGraphic(ACanvas:TCanvas;x,y:Integer;AGraphic:TGraphic;Faktor,Winkel:Double;PosIsCenter:Boolean=false);
  Procedure PaintText(ACanvas:TCanvas;Const s:String;x,y:Integer;Faktor,Winkel:Double;PosIsCenter:Boolean=false);
  Procedure ResetCanvas(ACanvas:TCanvas);
  procedure SetCanvasZoomAndRotation(ACanvas: TCanvas;Zoom:Double;Angle:Double;CenterpointX,CenterpointY:Double);

implementation

Function Grad2Rad(w:Double):Double;
  begin
     Result := w / 360 * PI *2;
  end;

Procedure PaintText(ACanvas:TCanvas;Const s:String;x,y:Integer;Faktor,Winkel:Double;PosIsCenter:Boolean=false);
var
  px,py:Integer;
begin
     SetCanvasZoomAndRotation(ACanvas , Faktor, Winkel, x,y);
     if PosIsCenter then
        begin
          px := Round( ACanvas.TextWidth(s) / 2 );
          py := Round( ACanvas.TextHeight(s) / 2 );
        end
     else
        begin
          px := 0;
          py := 0;
        end;

     ACanvas.TextOut(-px ,-py ,s);
     ResetCanvas(ACanvas);
end;




Procedure PaintGraphic(ACanvas:TCanvas;x,y:Integer;AGraphic:TGraphic;Faktor,Winkel:Double;PosIsCenter:Boolean=false);
var
  px,py:Integer;
begin
     if PosIsCenter then
        begin
          px := Round( AGraphic.Width / 2 );
          py := Round( AGraphic.Height / 2 );
        end
     else
        begin
          px := 0;
          py := 0;
        end;
     SetCanvasZoomAndRotation(ACanvas , Faktor, Winkel, x , y );
     ACanvas.Draw(-px ,-py ,AGraphic);
     ResetCanvas(ACanvas);
end;





Procedure ResetCanvas(ACanvas:TCanvas);
begin
   SetCanvasZoomAndRotation(ACanvas , 1, 0, 0,0);
end;

Procedure SetCanvasZoomAndRotation(ACanvas:TCanvas;Zoom:Double;Angle:Double;CenterpointX,CenterpointY:Double);
var
    form : tagXFORM;
    Winkel:Double;

begin
      Winkel := Grad2Rad(Angle);
      SetGraphicsMode(ACanvas.Handle, GM_ADVANCED);
      SetMapMode(ACanvas.Handle,MM_ANISOTROPIC);
      form.eM11 := Zoom * cos( Winkel);
      form.eM12 := Zoom *Sin( Winkel) ;
      form.eM21 := Zoom * (-sin( Winkel));
      form.eM22 := Zoom * cos( Winkel) ;
      form.eDx := CenterpointX;
      form.eDy := CenterpointY;
      SetWorldTransform(ACanvas.Handle,form);
end;

end.
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  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 03:53 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