AGB  ·  Datenschutz  ·  Impressum  







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

Resample oder Resize mit GDI+

Ein Thema von Schwedenbitter · begonnen am 25. Nov 2010 · letzter Beitrag vom 27. Mai 2019
Antwort Antwort
Seite 2 von 3     12 3      
Schwedenbitter

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

AW: Resample oder Resize mit GDI+

  Alt 29. Nov 2010, 09:55
Folgender Code funktioniert bei mir:
Delphi-Quellcode:
Procedure TBitmapEx.StretchGDI(Const NewWidth, NewHeight: Integer);
Var
  ScaleDown   : Boolean;
  W, H         : Integer;
  oldW, oldH   : Integer;
Begin
  If (self.Empty) Or
    ((NewWidth = 0) And (NewHeight = 0)) Or
    ((NewWidth = self.Width) And (NewHeight = self.Height)) Then
      Exit;

  W:=NewWidth;
  H:=NewHeight;
  oldW:=self.Width;
  oldH:=self.Height;

  If (W = 0) Then W:=H * self.Width Div self.Height;
  If (H = 0) Then H:=W * self.Height Div self.Width;

  ScaleDown:=True;
  If (W < self.Width) Or (H < self.Height) Then
    SetStretchBltMode(self.Canvas.Handle, Halftone)
  Else
  Begin
    ScaleDown:= False;
    self.Width:= W;
    self.Height:=H;
  End;
  StretchBlt(self.Canvas.Handle, 0, 0, W, H,
             self.Canvas.Handle, 0, 0, oldW, oldH,
             SRCCOPY);
  If (ScaleDown) Then
  Begin                                    
    self.Width:= W;
    self.Height:=H;
  End;
End;
Leider hatte ich am Wochenende wenig Zeit und den Code über GDI+ (noch) nicht zum Laufen bekommen. Ich scheitere im Moment daran, dass mir GdipSetInterpolationMode(Dest, 4); erklärt, ich würde falsche Parameter übergeben. Dabei ist Type Dest: Pointer und 4 sollte eigentlich Type InterpolationModeBicubic: Integer sein. Letztere sollte auch anstelle von Cardinal laufen, wie es wiederum in der uGDIUnit von Cardinal Emil Weiss definiert ist.

Dazu wieder 2 Fragen:
  1. Wenn GDI ohne zusätzliches Bitmap resizen kann, sollte das nicht auch mit GDI+ funktionieren? Dann brauchte ich doch kein Var Source, Dest: Pointer , sondern es sollte dann einfach eines reichen.
  2. Wo ist der Unterschied zwischen GdipDrawImageRect() und GdipDrawImageRectI() ? Einfach nur, dass die eine Funktion mit Gleitkommazahlen und die andere mit Integer funktioniert?
  3. Wo ist bei den Funktionen unter 2. der Unterschied zwischen Graphics und Image ? Beides ist laut den Erläuterungen zu GDI+ von MS ein Pointer bzw. bei Emil Weiss Cardinal.

Gruß & Dank, Alex
Alex Winzer
  Mit Zitat antworten Zitat
xaromz

Registriert seit: 18. Mär 2005
1.682 Beiträge
 
Delphi 2006 Enterprise
 
#12

AW: Resample oder Resize mit GDI+

  Alt 29. Nov 2010, 10:42
Hallo,
Dazu wieder 2 Fragen:
  1. Wenn GDI ohne zusätzliches Bitmap resizen kann, sollte das nicht auch mit GDI+ funktionieren? Dann brauchte ich doch kein Var Source, Dest: Pointer , sondern es sollte dann einfach eines reichen.
  2. Wo ist der Unterschied zwischen GdipDrawImageRect() und GdipDrawImageRectI() ? Einfach nur, dass die eine Funktion mit Gleitkommazahlen und die andere mit Integer funktioniert?
  3. Wo ist bei den Funktionen unter 2. der Unterschied zwischen Graphics und Image ? Beides ist laut den Erläuterungen zu GDI+ von MS ein Pointer bzw. bei Emil Weiss Cardinal.
(1) Du kannst schon mit einem Bitmap arbeiten, wenn Du das Bitmap verkleinert auf sich selbst zeichnest. Ob das richtig funktioniert oder Bildfehler erzeugt, kann ich Dir aber nicht sagen, das habe ich nie ausprobiert.

(2) Genau, der Unterschied ist, dass Du einmal Float und einmal Integer verwenden kannst.

(3) Image und Graphics sind zwei völlig unterschiedliche Klassen. Das ist quasi Bitmap und Canvas in der VCL. Ein Image hat immer ein Graphics, welches zum Manipulieren der Bitmapdaten dient. Ich vermute, dass deshalb Deine Interpolation fehlschlägt, weil Du der Funktion das Image übergibst, und nicht das entsprechende Graphics-Objekt.

Gruß
xaromz
I am a leaf on the wind - watch how I soar
  Mit Zitat antworten Zitat
Schwedenbitter

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

AW: Resample oder Resize mit GDI+

  Alt 29. Nov 2010, 15:44
Danke für diesen wertvollen Hinweis!
... Image und Graphics sind zwei völlig unterschiedliche Klassen. ... Ich vermute, dass deshalb Deine Interpolation fehlschlägt, weil Du der Funktion das Image übergibst, und nicht das entsprechende Graphics-Objekt.
Ich habe nun folgendes versucht, was aber nicht funktioniert. Ich komme sowei, dass ich ein GDI+ Image ausgehend von meinem TBitmap anlegen und ausgehend davon einen Zeiger auf das GDI+ Graphics bekomme. Trotzdem lässt sich der InterpolationMode nicht setzen mit dem Hinweis auf falsche Parameter:
Delphi-Quellcode:
Function GdipSetInterpolationMode(Out graphics: GdipImage;
  interpolationMode: GdipInterpolationMode): GdipStatus; Stdcall;
  External Gdip;
// GdipImage = Pointer; GdipInterpolationMode = Integer

Procedure TBitmapEx.StretchGdip(Const NewWidth, NewHeight: Integer;
  Const PreserveAspectRatio: Boolean = True);
Var
  Source : GdipImage; // = Pointer
  Dest : GdipGraphics; // = Pointer
  Stat : GdipStatus;
Begin
 If (Self.Empty) Then Exit;

  If (GdipCreateBitmapFromHBITMAP(self.Handle, self.Palette, Source) = Ok) Then
  Begin
    If (GdipGetImageGraphicsContext(Source, Dest) = Ok) Then
    Begin
      // Bis hierhin ist alles OK!
      Stat:=GdipSetInterpolationMode(Dest, 4);
      // Hier kommt der Hinweis auf falsche Parameter; leider nicht genau welcher der beiden möglichen...
      ShowMessage(GdipStatusMessage[Stat]);

    End;
    GdipDisposeImage(Source);
  End;
End;
Was mache in denn da falsch?

Ich scheitere nun schon seit letzter Woche an GdipSetInterpolationMode() . Ich habe alle möglichen Deklarationen angefangen von GDIPlus über IGDIPlus bis hin zu dem Uhr-Beispiel von EWeiss probiert. Im Grunde fehlen doch nur noch 3 Zeilen ((1)Interpolation Mode setzen (2) Bild zeichnen mit Draw und (3) ggf. auf das TBitmap zurückschieben).
Alex Winzer
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#14

AW: Resample oder Resize mit GDI+

  Alt 30. Nov 2010, 06:41
Die Vorgehensweise ist folgende..
1. Ein graphic obj erstellen
Code:
GdipCreateFromHDC(Hdc, graphics);
2. Setzen der Optimierungsmodis
Verschiedene modis die du verwenden kannst.
Smoothing, Interpolation, PixelOffset, CompositingMode..

Code:
GdipSetInterpolationMode(graphics, InterpolationModeHighQualityBicubic);
wobei InterpolationModeHighQualityBicubic den Wert 7 enthält..
QualityModeHigh := 2;
InterpolationModeHighQualityBicubic := QualityModeHigh + 5;

erst dann die Bilddatei als solche öffnen!

EDIT:
Zitat:
// Hier kommt der Hinweis auf falsche Parameter; leider nicht genau welcher der beiden möglichen...
Logisch ..

Du kannst ein img nicht in ein graphic object konvertieren..
Source und Destination müssen von typ graphics sein.

Zitat:
bzw. bei Emil Weiss Cardinal.
Spielt keine Rolle ist doch auslegungssache wie ich meine Function definiere.
Aber davon abgesehen ist es bei MS auch ein Cardinal .. "Pointer of Cardinal"

Bei mir gehts siehe Picture

gruss

Geändert von EWeiss ( 9. Jul 2019 um 08:32 Uhr)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#15

AW: Resample oder Resize mit GDI+

  Alt 30. Nov 2010, 10:17
Hier der Source zum Bild!
Vielleicht hilft es dir ja weiter

gruss

Geändert von EWeiss ( 9. Jul 2019 um 08:32 Uhr)
  Mit Zitat antworten Zitat
Schwedenbitter

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

AW: Resample oder Resize mit GDI+

  Alt 30. Nov 2010, 10:17
Die Vorgehensweise ist folgende..
1. Ein graphic obj erstellen
Code:
GdipCreateFromHDC(Hdc, graphics);
Ich komme genau bis hierher und dann nicht mehr weiter. Ich habe ein TBimap erstelle, dorthinein eine Datei geladen und dann GdipCreateFromHDC(TBitmap.Canvas.Handle, graphics); aufgerufen.

2. Setzen der Optimierungsmodis
Verschiedene modis die du verwenden kannst.
Smoothing, Interpolation, PixelOffset, CompositingMode..
Das bekomme ich eben nicht hin .
Ich übergebe jetzt graphics mit GdipSetInterpolationMode(graphics, 7) , wobei gilt:
Delphi-Quellcode:
Type
  GdipGraphics = Pointer;
  GdipInterpolationMode = Integer;

Function GdipSetInterpolationMode(Out graphics: GdipGraphics;
  interpolationMode: GdipInterpolationMode): GdipStatus; Stdcall;
  External Gdip;
Ich habe jetzt mal aus lauter Verzweiflung einen kurzen Testcode beigefügt mit der GdipAPI.inc, die ich selbst gebastelt und bislang benutzt habe. Vielleicht sieht ja jemand auf Anhieb meinen Fehler.

[EDIT]
Mist! Du warst schneller
[/EDIT]

Gruß, Alex
Angehängte Dateien
Dateityp: zip GdipTest_p.zip (18,9 KB, 17x aufgerufen)
Alex Winzer
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#17

AW: Resample oder Resize mit GDI+

  Alt 30. Nov 2010, 10:20
Siehe mein Source

gruss

Geändert von EWeiss (30. Nov 2010 um 10:39 Uhr)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#18

AW: Resample oder Resize mit GDI+

  Alt 30. Nov 2010, 10:40
Schmeiss mal das shit OUT aus "Out graphics: GdipGraphics" raus.

Dann funktioniert es auch.

gruss
  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
 
#19

AW: Resample oder Resize mit GDI+

  Alt 30. Nov 2010, 10:51
@Eweiss

Hi,

Ich hatte Ihn so verstanden daß er ein bestehenden GraphicObject direkt skalieren will ohne Umweg über ein File.

Ich habe mal eine Prozedur:
Delphi-Quellcode:
function DrawImageFromGraphic(source:TGraphic;
  DrawHdc: HDC;
  Percent: Integer;
  Interpolation: InterpolationMode = InterpolationModeDefault;
  Smoothing : SmoothingMode = SmoothingModeNone;
  PixelOffset : PixelOffsetMode = PixelOffsetModeNone;
  CompositingQuality: CompositingQualityMode = CompositingQualityDefault;
  CompositingMode: CompositingModeMode = CompositingModeSourceOver): Boolean;
in Deinen Code mit eingebaut, erfordert allerdings Classes,ActiveX wg.

function GdipLoadImageFromStreamICM(stream: ISTREAM;
out image: Cardinal): Integer; stdcall;
{$EXTERNALSYM GdipLoadImageFromStreamICM}

ist nur eine Quickhack, Du darfst falls Du es brauchen kannst das ganze gern optimieren.
Angehängte Dateien
Dateityp: zip Stretch.zip (61,8 KB, 39x aufgerufen)
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
EWeiss
(Gast)

n/a Beiträge
 
#20

AW: Resample oder Resize mit GDI+

  Alt 30. Nov 2010, 10:55
@Bummi
Zitat:
ist nur eine Quickhack, Du darfst falls Du es brauchen kannst das ganze gern optimieren.
Werde es mir mal anschauen..

Das Problem war aber eher das setzen des InterpolationMode
Die übergebenen Parameter müssen identisch sein sonst klappt das nicht
Er kann nicht bei Out graphis nicht einfach einen Pointer graphics übergeben ...
Wenn schon dann bitte das OUT entfernen dann funktioniert das auch.

gruss
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


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 23:39 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