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
EWeiss
(Gast)

n/a Beiträge
 
#1

AW: Resample oder Resize mit GDI+

  Alt 26. Nov 2010, 06:46
Schau hier mal rein
GDIClock
Da mußt auch nichts installieren.

gruss
  Mit Zitat antworten Zitat
Schwedenbitter

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

AW: Resample oder Resize mit GDI+

  Alt 26. Nov 2010, 11:32
Schau hier mal rein
GDIClock
Genau damit habe ich angefangen. Großes Lob im übrigen dafür. Zwar läuft die Uhr nicht bei mir (Zeiger und Untergrund passen nicht übereinander). Aber ich hatte das damals bestens für meine Experimente zum Drehen eines Bitmaps verwenden können und auch hier meine Anfänge gemacht.

Aus diesem Grunde bin ich ja auch dazu gekommen, dass ich keine fette Unit für das Resizen brauche, sondern mir das ganze selbst schlank und schnell zusammen bauen kann.
Aus schnell ist - wie man an diesem Thema sieht - nichts geworden. Aber ich habe keine andere Wahl. Denn im Moment mache ich das Scaling mit der GDI-Funktion (ohne "+")StretchBlt() und da leidet die Lesbarkeit unserer Dokumente erheblich. Beim Vergrößern (z.B. beim Ausdrucken mittels Printer.Canvas) ist das kein Problem. Aber wenn ich z.B. mit 300 oder 400 dpi eingescannte Bilder anwendungskonform auf 200 dpi bringen will, habe ich wirklich ein Problem.
Alex Winzer
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.663 Beiträge
 
Delphi 12 Athens
 
#3

AW: Resample oder Resize mit GDI+

  Alt 26. Nov 2010, 11:34
Hast Du mal versucht, vorher den StretchBltMode auf HALFTONE zu setzen? Damit habe ich recht gute Erfahrungen gemacht.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Schwedenbitter

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

AW: Resample oder Resize mit GDI+

  Alt 26. Nov 2010, 13:27
Hast Du mal versucht, vorher den StretchBltMode auf HALFTONE zu setzen? Damit habe ich recht gute Erfahrungen gemacht.
Wenn Du so direkt fragst: Nö!

Cool. Ich sehe grad, dass ich mich dann vermutlich bloß noch wegen des Speicherns als png-Datei mit GDI+ rumschlagen muss. Aber geschadet hat es trotzdem nichts und ich bleibe mal dran: womöglich sind die Ergebnisse mit GDI+ noch besser
Alex Winzer
  Mit Zitat antworten Zitat
Schwedenbitter

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

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
 
#6

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

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
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 08:55 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