AGB  ·  Datenschutz  ·  Impressum  







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

PNG in TImage falsch dargestellt

Ein Thema von tumo · begonnen am 14. Apr 2020 · letzter Beitrag vom 29. Apr 2020
Antwort Antwort
tumo

Registriert seit: 28. Apr 2014
46 Beiträge
 
Delphi 10.3 Rio
 
#1

AW: PNG in TImage falsch dargestellt

  Alt 14. Apr 2020, 21:12
Danke für die schnellen Antworten.

@Medium
Habe mir die graphics32 mal angeschaut. Nach fast einer halben Stunde Harreraufen mit den Delphi Settings ging es dann endlich. Es tut, was es muss, aber nicht so richtig was es soll. Nicht falsch verstehen, meine Bitmaps werden bildschön, skaliert und mit Transparenz angezeigt, aber die eigentliche Zuweisung der Bitmaps ist alles andere als verständlich für mich . Habe eine Liste mit Objekten, die Namen, ein paar andere Daten und eben auch die Bilder selbst speichern sollen. Diese sollen dann bei Bedarf angezeigt werden, aber irgendwie bekomme ich die Bitmap nicht von meinem Objekt in das Image32 gedrückt .

@Redeemer
Darf ich erfahren, was Palettenbilder sind?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: PNG in TImage falsch dargestellt

  Alt 14. Apr 2020, 21:26
Darf ich erfahren, was Palettenbilder sind?
Wie z.B. bei den 2-, 16- oder 256-Farben-Bitmaps.

PNG kann die Pixel jeweils als RGB speichern, aber es geht auch als Index in einer Farbpalette.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
tumo

Registriert seit: 28. Apr 2014
46 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: PNG in TImage falsch dargestellt

  Alt 14. Apr 2020, 21:42
Ah.
Nun, nicht das ich wüsste.
  Mit Zitat antworten Zitat
Redeemer

Registriert seit: 19. Jan 2009
Ort: Kirchlinteln (LK Verden)
1.115 Beiträge
 
Delphi 2009 Professional
 
#4

AW: PNG in TImage falsch dargestellt

  Alt 15. Apr 2020, 07:43
Ah.
Nun, nicht das ich wüsste.
Na ja, die PNG wird es dir nicht von selbst sagen. Da musst du mit einem geeigneten Programm nachschauen. Die Unterstützung für PNG8 mit Alphakanal ist sehr uneinheitlich.
Janni
2005 PE, 2009 PA, XE2 PA
  Mit Zitat antworten Zitat
tumo

Registriert seit: 28. Apr 2014
46 Beiträge
 
Delphi 10.3 Rio
 
#5

AW: PNG in TImage falsch dargestellt

  Alt 15. Apr 2020, 08:58
@Redeemer
Das war mir jetzt auch klar. Da ich aber alle PNGs einheitlich abgespeichert habe, vermute ich mal, entweder sind alle Pallettenbilder oder keins. Wenn dem nicht so ist, verstehe ich den Algorithmus von Paint.net nicht :/

@Medium
Perfekt, damit funktioniert es. Warum eine Zuweisung oder ein Assign nicht funktioniert, bleibt mir zwar ein Rätsel, aber das ist ja nicht so wichtig.

Final werden die Bilder in meiner Klasse so geladen:
Delphi-Quellcode:
fSrcPic, fDestPic: TBitmap32;
(...)
property SrcPicture: TBitmap32 read fSrcPic;
property DestPicture: TBitmap32 read fDestPic;
(...)
fSrcPic.Clear;
fDestPic.Clear;
if FileExists(fSrcPath) then
  LoadBitmap32FromPNG(fSrcPic, fSrcPath);

if FileExists(fDestPath) then
  LoadBitmap32FromPNG(fDestPic, fDestPath);
Und so werden sie dann dargestellt. e ist das ausgewählte Objekt.
Delphi-Quellcode:
Image1.Bitmap.SetSize(e.SrcPicture.Width, e.SrcPicture.Height);
e.SrcPicture.DrawTo(Image1.Bitmap);
(...)
//Image2.Bitmap.Clear; <-- Offenbar nicht nötig
Image2.Bitmap.SetSize(e.DestPicture.Width, e.DestPicture.Height);
e.DestPicture.DrawTo(Image2.Bitmap);
  Mit Zitat antworten Zitat
Rolf Frei

Registriert seit: 19. Jun 2006
655 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: PNG in TImage falsch dargestellt

  Alt 17. Apr 2020, 17:34
Mit der PNG Unit von D7 kann man transparente PNG problemlos laden und anzeigen. Dass das in Rio nicht mehr geht hat ganz andere Gründe. Da hat nämlich irgend ein Witzbold einfach den transparenten Teil auf fix schwarz gesetzt. Keine Ahung was man damit errreichen wollte, aber auf jeden Fall kann man so keine transparentten PNG's mehr an eine Bitmap assignen. Die Hintergrundfarbe müsste auf jeden Fall vom Anwender bestimmt werden und nciht fix Schwarz sein. In meinem Fall will ich da nämlich weiss als Hintergrundfarbe und nicht schwarz. Dafür müsste es ein Property geben.

Habe noch eine Beispiel PNG angehängt, die einen Alphchannel hat und transparent sein sollte. Dieses wird nun fix mit schwarzem Hintergrund angezeigt, wenn es an ein Bitmap assigned wird.

Das ist der entsprechende Code in der alten D7 PNGImage unit, der einwandfrei mit PNG's mit einem Alphachannel funktioniert:
Delphi-Quellcode:
**** PNGImage von D7 ****

{Assigns this TPNGImage to another object}
procedure TPNGImage.AssignTo(Dest: TPersistent);
{$IFDEF UseDelphi}
  function DetectPixelFormat: TPixelFormat;
  begin
    with Header do
    begin
      {Always use 24bits for partial transparency}
      if TransparencyMode = ptmPartial then
        DetectPixelFormat := pf24bit
      else
        case BitDepth of
          {Only supported by COLOR_PALETTE}
          1: DetectPixelFormat := pf1bit;
          2, 4: DetectPixelFormat := pf4bit;
          {8 may be palette or r, g, b values}
          8, 16:
            case ColorType of
              COLOR_RGB, COLOR_GRAYSCALE: DetectPixelFormat := pf24bit;
              COLOR_PALETTE: DetectPixelFormat := pf8bit;
              else raise Exception.Create('');
            end {case ColorFormat of}
          else raise Exception.Create('');
        end {case BitDepth of}
    end {with Header}
  end;
var
  TRNS: TChunkTRNS;
{$ENDIF}
begin
  {If the destination is also a TPNGImage make it assign}
  {this one}
  if Dest is TPNGImage then
    TPNGImage(Dest).AssignPNG(Self)
  {$IFDEF UseDelphi}
  {In case the destination is a bitmap}
  else if (Dest is TBitmap) and HeaderPresent then
  begin
    {Copies the handle using CopyImage API}
    TBitmap(Dest).PixelFormat := DetectPixelFormat;
    TBitmap(Dest).Width := Width;
    TBitmap(Dest).Height := Height;

    if Palette <> 0 then
      TBitmap(Dest).Palette := CopyPalette(Palette);

    if (TransparencyMode = ptmBit) then
    begin
      TRNS := Chunks.ItemFromClass(TChunkTRNS) as TChunkTRNS;
      TBitmap(Dest).TransparentColor := TRNS.TransparentColor;
      TBitmap(Dest).Transparent := True;
      SetStretchBltMode(TBitmap(Dest).Canvas.Handle, COLORONCOLOR);
      StretchDiBits(TBitmap(Dest).Canvas.Handle, 0, 0, Width, Height, 0, 0,
        Width, Height, Header.ImageData,
        pBitmapInfo(@Header.BitmapInfo)^, DIB_RGB_COLORS, SRCCOPY)

    end {if (TransparencyMode = ptmBit)}
    else
      TBitmap(Dest).Canvas.Draw(0, 0, Self);
  end
  else
    {Unknown destination kind}
    inherited AssignTo(Dest);
  {$ENDIF}
end;
Dieser Code wurde in Rio (oder auch schon füher), so abgeändert, dass da fix schwarz als Hintergrund verwendet wird. Folgende 2 Zeilen wurde da eingefügt, die nun den Effekt haben, das der Alpahachannel ncht merh funktioniert und alles, was transparent sein sollte, nun schwarz ist. (siehe ungefähr in der Mitte des Quelcodes)

TBitmap(Dest).Canvas.Brush.Color := 0;
TBitmap(Dest).Canvas.FillRect(Bounds(0,0,Width, Height));

Delphi-Quellcode:
**** PNGImage von 10.3 ***

{Assigns this TPngImage to another object}
procedure TPngImage.AssignTo(Dest: TPersistent);
{$IFDEF UseDelphi}
  function DetectPixelFormat: TPixelFormat;
  begin
    with Header do
    begin
      {Always use 24bits for partial transparency}
      if TransparencyMode = ptmPartial then
        DetectPixelFormat := pf24bit
      else
        case BitDepth of
          {Only supported by COLOR_PALETTE}
          1: DetectPixelFormat := pf1bit;
          2, 4: DetectPixelFormat := pf4bit;
          {8 may be palette or r, g, b values}
          8, 16:
            case ColorType of
              COLOR_RGB, COLOR_GRAYSCALE: DetectPixelFormat := pf24bit;
              COLOR_PALETTE: DetectPixelFormat := pf8bit;
              else raise Exception.Create('');
            end {case ColorFormat of}
          else raise Exception.Create('');
        end {case BitDepth of}
    end {with Header}
  end;
var
  TRNS: TChunkTRNS;
{$ENDIF}
begin
  {If the destination is also a TPngImage make it assign}
  {this one}
  if Dest is TPngImage then
    TPngImage(Dest).AssignPNG(Self)
  {$IFDEF UseDelphi}
  {In case the destination is a bitmap}
  else if (Dest is TBitmap) and HeaderPresent then
  begin
    TBitmap(Dest).SetSize(Width, Height);

    if (TransparencyMode = ptmPartial) then
    begin
      TBitmap(Dest).PixelFormat := pf32bit;
      TBitmap(Dest).AlphaFormat := afDefined;
// Die 2 folgenden Zeilen sind neu: Wer hat sich diesen Blödsinn überlegt?!
      TBitmap(Dest).Canvas.Brush.Color := 0; // <<< zumindest das hier sollte vom Anwender wählbar sein, also als Property zur Verfügung stehen.
      TBitmap(Dest).Canvas.FillRect(Bounds(0,0,Width, Height));
    end
    else
    begin
      TBitmap(Dest).PixelFormat := DetectPixelFormat;
      TBitmap(Dest).AlphaFormat := afIgnored;
    end;

    if Palette <> 0 then
      TBitmap(Dest).Palette := CopyPalette(Palette);

    if (TransparencyMode = ptmBit) then
    begin
      TRNS := TChunkTRNS(Chunks.ItemFromClass(TChunkTRNS));
      TBitmap(Dest).TransparentColor := TRNS.TransparentColor;
      TBitmap(Dest).Transparent := True;
      SetStretchBltMode(TBitmap(Dest).Canvas.Handle, COLORONCOLOR);
      StretchDiBits(TBitmap(Dest).Canvas.Handle, 0, 0, Width, Height, 0, 0,
        Width, Height, Header.ImageData,
        pBitmapInfo(@Header.BitmapInfo)^, DIB_RGB_COLORS, SRCCOPY)

    end {if (TransparencyMode = ptmBit)}
    else
      TBitmap(Dest).Canvas.Draw(0, 0, Self);
  end
  else
    {Unknown destination kind}
    inherited AssignTo(Dest);
  {$ENDIF}
end;
Eine Zuweisung einer PNG mit Alphachannel an eine Bitmap mit Assign, wird deswegen immer mit schwarzem Hintergrund dargestellt. Mit der alten Unit von D7 funktioniert das noch tadellos und ist bei mir seit Jahren so im Einsatz, ohne dass ich da auf GDI+ oder ähnliches zugreiffen müsste. In Rio ist da was "kaputt" gemacht worden.
Angehängte Grafiken
Dateityp: png EP50_adhoc_paris-01.png (318,2 KB, 13x aufgerufen)

Geändert von Rolf Frei (17. Apr 2020 um 17:53 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: PNG in TImage falsch dargestellt

  Alt 17. Apr 2020, 17:37
Das musst du schnell noch melden, damit der Bugfix heute noch ins Delphi 10.4 rein kommt, bevor es raus kommt.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.688 Beiträge
 
Delphi 2007 Enterprise
 
#8

AW: PNG in TImage falsch dargestellt

  Alt 17. Apr 2020, 17:53
Mit der PNG Unit von D7 kann man transparente PNG problemlos laden und anzeigen. Dass das in Rio nicht mehr geht hat ganz andere Gründe. Da hat nämlich irgend ein Witzbold einfach den transparenten Teil auf fix schwarz gesetzt.
Ja Moment, das stimmt nur teilweise. Die Farbe wird auf "0" gesetzt, d.h. 100% transparent Schwarz! Sichtbares Schwarz wäre clBlack, oder rgb(0, 0, 0) oder $FF000000 oder 4278190080. Das ist meines Erachtens nach richtig, und letztlich nur ein Initialisieren des soeben ggf. in der Größe geänderten Bitmaps um Restmüll aus dem Speicherbereich sicher zu entfernen.

Das Problem müsste später auftreten; da wo dieses Bitmap auf einen Bildschirm-Canvas gemalt wird. Und DAS ist wiederum Aufgabe der GDI. Eventuell wurde hier etwas an den Aufrufen geändert, das kann ich grad nicht prüfen, aber ich habe gute Erinnerung daran, dass ich mit Alphakanälen unter purer GDI immer irgendwo Probleme hatte. Mindestens in Delphi 7, aber auch noch in 2007. Mit neueren hatte ich bislang nicht mit Transparenzen zu tun.
"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
TurboMagic

Registriert seit: 28. Feb 2016
Ort: Nordost Baden-Württemberg
3.038 Beiträge
 
Delphi 12 Athens
 
#9

AW: PNG in TImage falsch dargestellt

  Alt 19. Apr 2020, 14:09
Mit der PNG Unit von D7 kann man transparente PNG problemlos laden und anzeigen. Dass das in Rio nicht mehr geht hat ganz andere Gründe. Da hat nämlich irgend ein Witzbold einfach den transparenten Teil auf fix schwarz gesetzt. Keine Ahung was man damit errreichen wollte, aber auf jeden Fall kann man so keine transparentten PNG's mehr an eine Bitmap assignen. Die Hintergrundfarbe müsste auf jeden Fall vom Anwender bestimmt werden und nciht fix Schwarz sein. In meinem Fall will ich da nämlich weiss als Hintergrundfarbe und nicht schwarz.
Hast du mal geschaut, ob das Problem schon in QP gemeldet ist und fals nicht würdest du das dann bitte melden?
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.688 Beiträge
 
Delphi 2007 Enterprise
 
#10

AW: PNG in TImage falsch dargestellt

  Alt 15. Apr 2020, 07:29
[...]irgendwie bekomme ich die Bitmap nicht von meinem Objekt in das Image32 gedrückt .
Grundsätzlich sollte das mit einem TBitmap32.DrawTo(TImage32.Bitmap) erledigt sein, ggf. noch ein TImage32.Bitmap.Clear vorausgeschickt. Zeig im Zweifel doch mal das Stück Code, in dem das gemacht wird. Dann kann man evtl. konkreter helfen.
"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
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 22:25 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