AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi Bilder [mit/ohne Transparenz] in universelles Format bringen
Thema durchsuchen
Ansicht
Themen-Optionen

Bilder [mit/ohne Transparenz] in universelles Format bringen

Offene Frage von "Jens01"
Ein Thema von berens · begonnen am 16. Aug 2016 · letzter Beitrag vom 17. Aug 2016
Antwort Antwort
Seite 1 von 2  1 2      
berens

Registriert seit: 3. Sep 2004
441 Beiträge
 
Delphi 10.4 Sydney
 
#1

AW: Bilder [mit/ohne Transparenz] in universelles Format bringen

  Alt 16. Aug 2016, 14:39
Danke für die Beiträge.

Zuerst nochmal "sorry" @EWeiss, beim schreiben meiner ersten Antwort hatte ich Deinen Post nur bis "Was möchtest du also?" gesehen/gelesen und dachte ursprünglich mein erster Post wäre unklar.

Deinen Code habe ich mir angeschaut, weiß allerdings nicht so Recht, wie ich das auf Delphi übertragen soll bzw. was der Code macht. Von den Prozedurnamen her scheinst Du eine Datei zu laden, die Metadaten zu entfernen und die Datei wieder zu speichern. Den eigentlichen Transfer machst du mit DrawImage, und scheinst direkt auf eine TGraphic zu zeichnen (geht in Delphi nicht?), bzw. auf ein Bitmap (wieder Problem mit 32Bit/Alpha bzw. dem Pixelformat ansich). Dafür bin ich leider nicht gut genug in C drin, damit ich das auch nur gedanklich übertragen könnte, vll. kannst du nochmal 1-2 Kommentare zu den Zeilen machen, bitte?

Mein aktueller Lösungsweg sieht dank @bytecook so aus, dass ich den Umweg über TBitmap32 und TPortableNetworkGraphic32 gehe. Abgesehen von vielen, vielen Units die nun zusätzlich in meinem Projekt für eine Quelltextzeile mitverwendet werden müssen (jammern auf hohem Nivea ) kann ich nicht direkt von TBitmap32 in einen MemoryStream speichern, da das Format (logischerweise) anders ist als TBitmap, und somit TglBitmap2D das nicht laden kann. Also Umweg über PNG-Komponente, das geht generell, ABER: Trotz eines wirklich schnellen Rechners dauert png32.Assign bald über 10 Sekunden. Wenn der Benutzer also 10-20 Bilder einfügt, dauert das Starten vom Programm dann bald 2-3 Minuten, das kann ja dann wohl auch nicht sein.

Wo habe ich den Fehler, wie geht es anders?

@Sherlock: Ich befürchte, TPortableNetworkGraphic32 benutzt vielleicht auch WIC und ist deshalb so langsam?

Primär die Frage: Wie erzeuge ich ein leeres TPNGImage mit 32 Bit Farbtiefe incl. Alphakanal?

   png := TPngImage.CreateBlank(COLOR_RGBALPHA, 32, 2048, 1024); erzeugt:
Zitat:
---------------------------
Benachrichtigung über Debugger-Exception
---------------------------
Im Projekt bla.exe ist eine Exception der Klasse EPNGInvalidSpec mit der Meldung '"Portable Network Graphics" konnte nicht erstellt werden, weil ungültige Bildtypparameter angegeben wurden.' aufgetreten.

Delphi-Quellcode:
uses
  ..., GR32, gr32_png;

var
  bmp32: TBitmap32;
  png32: TPortableNetworkGraphic32;
begin
   bmp32 := TBitmap32.Create;
   bmp32.Width := 2048; // zum testen
   bmp32.Height := 1024;
   bmp32.Canvas.Draw(0, 0, tmpImage.Picture.Graphic); // zum Testen auch keine Skalierung etc.

   png32 := TPortableNetworkGraphic32.Create;
   png32.Assign(bmp32);

   ms := TMemoryStream.Create;
   ms.Position := 0;
   png32.SaveToStream(ms);
// bmp32.SaveToStream(ms); // geht nicht, TglBitmap2D kann das dann nicht wieder einlesen
   ms.Position := 0;
   LoadFromStream(ms);
   FreeAndNil(ms);

   GenTexture(True); // geladene Textur an OpenGL übergeben

   FreeAndNil(png32);
   FreeAndNil(bmp32);
Edit:
Ich habe es nun mit WIC versucht, und es geht einfach und schnell:

Delphi-Quellcode:
var
  wic: TWICImage;
begin
ms := TMemoryStream.Create;
ms.Position := 0;
wic := TWICImage.Create;
wic.LoadFromFile(_Filename);
wic.ImageFormat := wifPng;
wic.SaveToStream(ms);
ms.Position := 0;
   LoadFromStream(ms);
   FreeAndNil(ms);

   GenTexture(True); // geladene Textur an OpenGL übergeben
Aktuell kann ich nun sowohl meine .png wie auch .bmp-Datei korrekt laden. Es ist halt nur die Frage, wie ich das nun noch ohne AlphaVerlust skaliere. Der Link zum verkleinern von TWicImage erfordert das IWICBitmapScaler aus der windowscodec.dll. Gibt es bei Delphi 2010 standardmäßig nicht. Muss ich gleich mal schauen, wie ich das Bild klein bekomme...

Geändert von berens (16. Aug 2016 um 14:54 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von bytecook
bytecook

Registriert seit: 6. Aug 2010
Ort: Dornbirn
151 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Bilder [mit/ohne Transparenz] in universelles Format bringen

  Alt 16. Aug 2016, 14:59
Danke für die Beiträge.

Delphi-Quellcode:
uses
  ..., GR32, gr32_png;

var
  bmp32: TBitmap32;
  png32: TPortableNetworkGraphic32;
begin
   bmp32 := TBitmap32.Create;
   bmp32.Width := 2048; // zum testen
   bmp32.Height := 1024;
   bmp32.Canvas.Draw(0, 0, tmpImage.Picture.Graphic); // zum Testen auch keine Skalierung etc.

   png32 := TPortableNetworkGraphic32.Create;
   png32.Assign(bmp32);

   ms := TMemoryStream.Create;
   ms.Position := 0;
   png32.SaveToStream(ms);
// bmp32.SaveToStream(ms); // geht nicht, TglBitmap2D kann das dann nicht wieder einlesen
   ms.Position := 0;
   LoadFromStream(ms);
   FreeAndNil(ms);

   GenTexture(True); // geladene Textur an OpenGL übergeben

   FreeAndNil(png32);
   FreeAndNil(bmp32);

Delphi-Quellcode:

uses
     ...
     Gr32,
     GR32_Png,
     GR32_PortableNetworkGraphic;

...

  (** PNG - Routinen **)
  function SaveAsPng (Const FileName : String; ABmp : TBitmap32) : Boolean;
  function LoadPng (Const FileName : String; ABmp : TBitmap32) : Boolean;


(******************************************************************************)

(** PNG - Routinen - QnD                                                     **)

(******************************************************************************)

function SaveAsPng (Const FileName : String; ABmp : TBitmap32) : Boolean;

  var APng : TPortableNetworkGraphic32;

  begin
    try
      APng := TPortableNetworkGraphic32.Create;
      APng.Assign(ABmp);
      APng.SaveToFile(FileName);
      Result := True;
    except
      Result := False;
    end;
    APng.Free;
  end;
(******************************************************************************)
function LoadPng (Const FileName : String; ABmp : TBitmap32) : Boolean;

  var APng : TPortableNetworkGraphic32;

  begin
    try
      APng := TPortableNetworkGraphic32.Create;
      APng.LoadFromFile(FileName);
      APng.AssignTo(ABmp);
      Result := True;
    except
      Result := False;
    end;
    APng.Free;
  end;
(******************************************************************************)


procedure TForm1.LadePng

  var ABmp : TBitmap32;

  begin
    ABmp := TBitmap.Create();
    LoadPng ('Bart.png', ABmp);

    ... tuwas ...

    FreeAndNil(ABmp);

  end;

So sollte es klappen. TPortableNetworkGraphic32 funktioniert nativ, ohne DirectX ...
Peter
  Mit Zitat antworten Zitat
Benutzerbild von Sherlock
Sherlock

Registriert seit: 10. Jan 2006
Ort: Offenbach
3.821 Beiträge
 
Delphi 12 Athens
 
#3

AW: Bilder [mit/ohne Transparenz] in universelles Format bringen

  Alt 16. Aug 2016, 15:01
Also sooo langsam ist ein TWICImage dann doch nicht. Ein LoadFromFile dauert weniger als eine Sekunde...natürlich hängt es etwas von der Dateigröße und dem Speicherort ab.

Sherlock
Oliver
Geändert von Sherlock (Morgen um 16:78 Uhr) Grund: Weil ich es kann
  Mit Zitat antworten Zitat
Benutzerbild von bytecook
bytecook

Registriert seit: 6. Aug 2010
Ort: Dornbirn
151 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Bilder [mit/ohne Transparenz] in universelles Format bringen

  Alt 16. Aug 2016, 15:08
Also sooo langsam ist ein TWICImage dann doch nicht. Ein LoadFromFile dauert weniger als eine Sekunde...natürlich hängt es etwas von der Dateigröße und dem Speicherort ab.

Sherlock
Stimmt Hängt aber davon ab, wie groß die Texturen oder Graphiken sein sollen - und ob du auf deinem System DirectX installieren kannst...
Peter
  Mit Zitat antworten Zitat
berens

Registriert seit: 3. Sep 2004
441 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Bilder [mit/ohne Transparenz] in universelles Format bringen

  Alt 16. Aug 2016, 15:10
Mit TWICImage geht es durchaus schnell und zuverlässig! (Oben habe ich den Code mit Edit nachgetragen um nicht Antworten zu spammen).

Nur wie verkleinere ich die Bilder? Wie gesagt, der verlinkte Code erfordert Units, die ich nicht habe...

Edit: Danke @bytecook für den Code, aber ich lade explizit nicht über die TPortableNetworksGraphic32, weil die Dateien ja auch was anderes als .png sein können. Kann natürlich sein, dass die wegen Vererbung von TBitmap32 auch JPEG etc. lädt, aber naja...

Natürlich ist TPicture stilvoller als TImage, mal schauen, was im fertigen Code übrigbleibt.
Delphi 10.4 32-Bit auf Windows 10 Pro 64-Bit, ehem. Delphi 2010 32-Bit auf Windows 10 Pro 64-Bit

Geändert von berens (16. Aug 2016 um 15:13 Uhr)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#6

AW: Bilder [mit/ohne Transparenz] in universelles Format bringen

  Alt 16. Aug 2016, 15:12
Ich kenn das TWICImage nicht..
Aber wenn das auf GDI+ basiert könnte das verkleinern mit DrawImageRectRectI funktionieren.

gruss
  Mit Zitat antworten Zitat
Benutzerbild von bytecook
bytecook

Registriert seit: 6. Aug 2010
Ort: Dornbirn
151 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Bilder [mit/ohne Transparenz] in universelles Format bringen

  Alt 16. Aug 2016, 15:16
Ich kenn das TWICImage nicht..
Aber wenn das auf GDI+ basiert könnte das verkleinern mit DrawImageRectRectI funktionieren.

gruss
TWicImage ist bei Delphi mit an Bord...

Aber: Hier schon mal nachgesehen? http://www.dev-center.de/header/glbitmap
Imho solltest du ganz einfach die Textur laden können, da png unterstützt wird.

Ansonsten mal im DGL Forum Bergmann89 fragen, der gited ja die TGlBitmap...
Peter
  Mit Zitat antworten Zitat
Benutzerbild von Sherlock
Sherlock

Registriert seit: 10. Jan 2006
Ort: Offenbach
3.821 Beiträge
 
Delphi 12 Athens
 
#8

AW: Bilder [mit/ohne Transparenz] in universelles Format bringen

  Alt 16. Aug 2016, 15:18
Die Unit winapi.wincodec gibt es unter D2010 noch nicht?

Eventuell ohne Namespace...oder nur winapi.

Sherlock
Oliver
Geändert von Sherlock (Morgen um 16:78 Uhr) Grund: Weil ich es kann
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.557 Beiträge
 
Delphi 12 Athens
 
#9

AW: Bilder [mit/ohne Transparenz] in universelles Format bringen

  Alt 16. Aug 2016, 15:25
Liegt im XE in der Graphics.pas und Wincodec.pas

Einen HDC finde ich auch nicht, wo man ein TCanvas dran hängen könnte.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (16. Aug 2016 um 15:34 Uhr)
  Mit Zitat antworten Zitat
berens

Registriert seit: 3. Sep 2004
441 Beiträge
 
Delphi 10.4 Sydney
 
#10

AW: Bilder [mit/ohne Transparenz] in universelles Format bringen

  Alt 16. Aug 2016, 15:20
Leider verfügt weder TWicImage nach TPNGImage (als "Mittelsmann"), noch TPortableNetworkGraphic32 über einen Canvas, auf den ich mit Stretchdraw zeichen könnte.

> Ich kenn das TWICImage nicht..
Der Aussage kam nicht von mir, ich kann es ja problemlos benutzen.

Auf glBitmap soll das ganze ja letztendlich drauf. Leider _muss_ ich die Graphiken bearbeiten (verkleinern) bevor ich sie an glBitmap übergebe. Und je nach Dateiformat kann es mit glBitmap zu gewaltigen Problemen kommen, deshalb bin _ich_ für eine gültige Graphik zuständig und muss diese sicherstellen.

Edit: Es gibt tatsächlich die WinCodec Unit, damit geht das Resize (hatte versucht "WindowsCodec" wie in der Hilfe beschrieben zu verwenden). Jetzt muss ich den Code nur noch für Breite und Höhe anpassen:

Delphi-Quellcode:
procedure ResizeImage(aWICImage: TWICImage; NewWidth:Integer; NewHeight: Integer);
var
  scale: IWICBitmapScaler;
  wicBitmap: IWICBitmap;
begin
  if Assigned(aWICImage) then
  begin
    aWICImage.ImagingFactory.CreateBitmapScaler( scale);
    scale.Initialize(aWICImage.Handle, NewWidth, NewHeight, WICBitmapInterpolationModeFant);
    aWICImage.ImagingFactory.CreateBitmapFromSourceRect(scale, 0,0,NewWidth, NewHeight, wicBitmap);
    if Assigned(wicBitmap) then
      aWICImage.Handle := wicBitmap;
  end;
end;
Delphi 10.4 32-Bit auf Windows 10 Pro 64-Bit, ehem. Delphi 2010 32-Bit auf Windows 10 Pro 64-Bit

Geändert von berens (16. Aug 2016 um 15:31 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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:12 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