Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Bitmap aus Clipboard laden (https://www.delphipraxis.net/217016-bitmap-aus-clipboard-laden.html)

Amateurprofi 8. Apr 2025 00:36

Bitmap aus Clipboard laden
 
Liste der Anhänge anzeigen (Anzahl: 3)
Ich habe eine .bmp-Datei
Die öffne ich mit Paint.
In Paint wird das Bild korrekt angezeigt (Bild_1).
Mit Ctrl-A und Ctrl-C kopiere ich die ins Clipboard,
Dann lade ich die aus dem Clipboard (siehe unten) und speichere sie.
Die gespeicherte Datei öffne ich mit Paint.
Die Datei wird angezeigt, aber mit verfälschten Farben (Bild_2).
Ähnliches passiert, wenn ich die Originaldatei mit Paint öffne, ins Clipboard kopiere und mit Photoshop aus dem Clipboard lade (Bild_3).
2 Fragen
1) Was ist der Fehler?
2) Wie kann ich herausfinden, welche Daten (Speicherauszug) tatsächlich im Clipboard sind?

Hab gerade gemerkt, das man die Bilder nicht in vergrößerter Form anzeigen kann.
Die Farben der aus dem Clipboard geladenen Bilder scheinen Systemfarben (clActiveBorder .. clWindowText) zu sein.

Prozedur zum Laden aus dem Clipboard:
Delphi-Quellcode:
PROCEDURE TMain.Test;
FUNCTION FullPath(const Dsn:String):String;
begin
   Result:=ExtractFilePath(ParamStr(0))+Dsn;
end;
var Bmp:TBitmap; Data:THandle; Palette:HPalette;
begin
   if ClipBoard.HasFormat(CF_Bitmap) then begin
      Bmp:=TBitmap.Create;
      ClipBoard.Open;
      try
         Data:=GetClipboardData(CF_BITMAP);
         Palette:=GetClipboardData(CF_PALETTE);
         Bmp.LoadFromClipboardFormat(CF_BITMAP,Data,Palette);
      finally
         ClipBoard.Close;
      end;
      Bmp.SaveToFile(FullPath('Test.bmp'));
      Bmp.Free;
   end;
end;

Sinspin 8. Apr 2025 09:54

AW: Bitmap aus Clipboard laden
 
Das ist jetzt keine Antwort auf deine Frage, aber warum öffnest Du mit Paint?

Gausi 8. Apr 2025 10:25

AW: Bitmap aus Clipboard laden
 
Im Beispiel-Code für LoadFromClipboardFormat in der Delphi-Hilfe wird mit "0" für den Paletten-Parameter gearbeitet. Liegt es vielleicht daran?

Für ein TPicture ist der Beispielcode ja einfach nur
Delphi-Quellcode:
Picture.LoadFromClipboardFormat(cf_BitMap, ClipBoard.GetAsHandle(cf_Bitmap), 0);

peterbelow 8. Apr 2025 10:41

AW: Bitmap aus Clipboard laden
 
Zitat:

Zitat von Amateurprofi (Beitrag 1547883)
Ich habe eine .bmp-Datei
Die öffne ich mit Paint.
In Paint wird das Bild korrekt angezeigt (Bild_1).
Mit Ctrl-A und Ctrl-C kopiere ich die ins Clipboard,
Dann lade ich die aus dem Clipboard (siehe unten) und speichere sie.
Die gespeicherte Datei öffne ich mit Paint.
Die Datei wird angezeigt, aber mit verfälschten Farben (Bild_2).
Ähnliches passiert, wenn ich die Originaldatei mit Paint öffne, ins Clipboard kopiere und mit Photoshop aus dem Clipboard lade (Bild_3).
2 Fragen
1) Was ist der Fehler?
2) Wie kann ich herausfinden, welche Daten (Speicherauszug) tatsächlich im Clipboard sind?

Sieh dir mal dieses Beispiel in der online-Hilfe an.

Dein Problem kommt vermutlich daher, daß Du eine Palette angibst. Die meisten Bitmap-Formate verwenden aber keine, daher könnte das dazu führen, das die Bitmap als in das 256-Farben Format konvertiert wird.

Die momentan verfügbaren Formate im Clipboard bekommst Du über die Clipboard.Formats-Property. Einen Text-Namen aus der ID des Formats liefert die folgende Routine mit Hilfe der GetclipboardFormatName API-Funktion.

Delphi-Quellcode:
{!
<summary>
 Get a string name for a clipboard format.</summary>
<returns>
 the name the format was registered with, if it is a custom format, or
 the symbolic name for the known predefined formats. The string
 'unknown format' is returned for a format that cannot be identified.</returns>
<param name="fmt">is the format to get a name for.</param>
}
function GetClipFmtname(fmt: Cardinal): string;
const
  MaxChars = 128;
var
  buf: array[0..MaxChars] of Char;
  Len: Integer;
begin
  Len := GetclipboardFormatName(fmt, buf, MaxChars);
  if Len <> 0 then
    SetString(Result, buf, Len)
  else
    case fmt of
      1: Result := 'CF_TEXT';
      2: Result := 'CF_BITMAP';
      3: Result := 'CF_METAFILEPICT';
      4: Result := 'CF_SYLK';
      5: Result := 'CF_DIF';
      6: Result := 'CF_TIFF';
      7: Result := 'CF_OEMTEXT';
      8: Result := 'CF_DIB';
      9: Result := 'CF_PALETTE';
      10: Result := 'CF_PENDATA';
      11: Result := 'CF_RIFF';
      12: Result := 'CF_WAVE';
      13: Result := 'CF_UNICODETEXT';
      14: Result := 'CF_ENHMETAFILE';
      15: Result := 'CF_HDROP';
      16: Result := 'CF_LOCALE';
      17: Result := 'CF_DIBV5';
      $0080: Result := 'CF_OWNERDISPLAY';
      $0081: Result := 'CF_DSPTEXT';
      $0082: Result := 'CF_DSPBITMAP';
      $0083: Result := 'CF_DSPMETAFILEPICT';
      $008E: Result := 'CF_DSPENHMETAFILE';
      $0200..$02FF: Result := 'private format';
      $0300..$03FF: Result := 'GDI object';
    else
      Result := 'unknown format';
    end; {Case}
end;

Amateurprofi 8. Apr 2025 14:47

AW: Bitmap aus Clipboard laden
 
Zitat:

Zitat von Sinspin (Beitrag 1547891)
Das ist jetzt keine Antwort auf deine Frage, aber warum öffnest Du mit Paint?

Aus unterschiedlichen Gründen.
Zum Bespiel, um bestimmte Bereiche eines Bildes zu entfernen.

Amateurprofi 8. Apr 2025 14:59

AW: Bitmap aus Clipboard laden
 
Zitat:

Zitat von Gausi (Beitrag 1547892)
Im Beispiel-Code für LoadFromClipboardFormat in der Delphi-Hilfe wird mit "0" für den Paletten-Parameter gearbeitet. Liegt es vielleicht daran?

Für ein TPicture ist der Beispielcode ja einfach nur
Delphi-Quellcode:
Picture.LoadFromClipboardFormat(cf_BitMap, ClipBoard.GetAsHandle(cf_Bitmap), 0);

Danke, Gausi.

Nein ,daran liegt es nicht.
Mit 0 statt Palette machte ich es ursprünglich.
Dann sah ich dieses:
Delphi-Quellcode:
procedure TClipboard.AssignToBitmap(Dest: TBitmap);
var
  Data: THandle;
  Palette: HPALETTE;
begin
  Open;
  try
    Data := GetClipboardData(CF_BITMAP);
    Palette := GetClipboardData(CF_PALETTE);
    Dest.LoadFromClipboardFormat(CF_BITMAP, Data, Palette);
  finally
    Close;
  end;
end;
Zur Vollständigkeit:
Nach Palette :=
Delphi-Quellcode:
GetClipboardData(CF_PALETTE);
ist Palette = 0.

Amateurprofi 8. Apr 2025 15:21

AW: Bitmap aus Clipboard laden
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von peterbelow (Beitrag 1547893)
Dein Problem kommt vermutlich daher, daß Du eine Palette angibst. Die meisten Bitmap-Formate verwenden aber keine, daher könnte das dazu führen, das die Bitmap als in das 256-Farben Format konvertiert wird.

Die momentan verfügbaren Formate im Clipboard bekommst Du über die Clipboard.Formats-Property. Einen Text-Namen aus der ID des Formats liefert die folgende Routine mit Hilfe der GetclipboardFormatName API-Funktion.

Danke peterbelow.
Zu "Dein Problem kommt vermutlich ..."
Nein.
Bei dem von mir benutzten Code ist nach
Delphi-Quellcode:
Palette:=GetClipboardData(CF_PALETTE);
Palette = 0.

Zu "Die momentan verfügbaren Formate"
Ich habe in den meisten meiner Programme die Möglichkeit implementiert, mir die vorhandenen Formate anzeigen zu lassen.
Bei dem in #1 geschilderten Problem ist es das in Bild_4 gezeigte.
Unabhängig davon: Ich habe mich vielleicht falsch ausgedrückt.
Ich möchte nicht sehen, welche Formate vorhanden sind, sondern die Daten selbst. Deshalb schrieb ich "(Speicherauszug)".

Redeemer 8. Apr 2025 15:42

AW: Bitmap aus Clipboard laden
 
Ich benutze aktuellen den Befehl
Delphi-Quellcode:
Image1.Picture.Bitmap.Assign(Clipboard)
. Was passiert in diesem Fall bei dem Bild?

Sinspin 8. Apr 2025 18:27

AW: Bitmap aus Clipboard laden
 
Zitat:

Zitat von Amateurprofi (Beitrag 1547911)
Zitat:

Zitat von Sinspin (Beitrag 1547891)
Das ist jetzt keine Antwort auf deine Frage, aber warum öffnest Du mit Paint?

Aus unterschiedlichen Gründen.
Zum Bespiel, um bestimmte Bereiche eines Bildes zu entfernen.

Das geht aber auch in Delphi auch. Nur halt eventuell nicht mit Canvas, sondern der Gr32 oder was in der Art.

jaenicke 8. Apr 2025 18:31

AW: Bitmap aus Clipboard laden
 
Mit InsideClipboard kannst du die Formate sehen und den Inhalt direkt als Binärdatei speichern:
https://www.nirsoft.net/utils/inside_clipboard.html

Amateurprofi 8. Apr 2025 21:27

AW: Bitmap aus Clipboard laden
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von Redeemer (Beitrag 1547916)
Ich benutze aktuellen den Befehl
Delphi-Quellcode:
Image1.Picture.Bitmap.Assign(Clipboard)
. Was passiert in diesem Fall bei dem Bild?

Danke Redeemer.
Hab ich probiert. Auch hier sind die Farben auf gleiche Weise verfälscht.
Hab noch einmal die Bilder in vergrößerter Form hochgeladen (Bild_5).
Links das Original, rechts das verfälschte Bild.

Amateurprofi 8. Apr 2025 21:44

AW: Bitmap aus Clipboard laden
 
Zitat:

Zitat von Sinspin (Beitrag 1547920)
Zitat:

Zitat von Amateurprofi (Beitrag 1547911)
Zitat:

Zitat von Sinspin (Beitrag 1547891)
Das ist jetzt keine Antwort auf deine Frage, aber warum öffnest Du mit Paint?

Aus unterschiedlichen Gründen.
Zum Bespiel, um bestimmte Bereiche eines Bildes zu entfernen.

Das geht aber auch in Delphi auch. Nur halt eventuell nicht mit Canvas, sondern der Gr32 oder was in der Art.

Das geht auch mit Canvas, aber warum erst eine Prozedur schreiben, wenn Paint das Zuschneiden von Bildern perfekt macht?
Ich könnte auch alles mit Buntstiften abmalen. Will ich aber nicht.

Amateurprofi 8. Apr 2025 21:57

AW: Bitmap aus Clipboard laden
 
Zitat:

Zitat von jaenicke (Beitrag 1547921)
Mit InsideClipboard kannst du die Formate sehen und den Inhalt direkt als Binärdatei speichern:
https://www.nirsoft.net/utils/inside_clipboard.html

Danke jaenicke.
Hab ich runtergeladen.
Aber das Programm will unbedingt meinen PC reparieren und ist von dieser Idee nicht abzubringen.
Deshalb wieder gelöscht.
Gibt es keine Möglichkeit, mit Delphi an die Binärdaten heranzukommen?

jaenicke 8. Apr 2025 22:37

AW: Bitmap aus Clipboard laden
 
Ich vermute einmal, dass das Problem die Konvertierung als Bitmap ist, denn Paint legt in die Zwischenablage unter anderem CF_DIB und PNG ab, aber nicht CF_Bitmap. Wenn du also CF_Bitmap abrufst, muss Windows den Inhalt der Zwischenablage zuerst konvertieren.

Zitat:

Zitat von Amateurprofi (Beitrag 1547925)
Aber das Programm will unbedingt meinen PC reparieren und ist von dieser Idee nicht abzubringen.

Solch eine Funktion hat das Tool gar nicht. Was meinst du damit? Hast du vielleicht auf einen Werbebanner auf der Seite geklickt statt auf den Download?

Zitat:

Zitat von Amateurprofi (Beitrag 1547925)
Gibt es keine Möglichkeit, mit Delphi an die Binärdaten heranzukommen?

Doch, aber dann hast du auch wirklich nur die reinen Bildinformationen:
Delphi-Quellcode:
function GetClipboardDIBData(const ATarget: TMemoryStream): Boolean;
var
  ClipboardHandle: THandle;
  Src: Pointer;
  Size: Integer;
begin
  if Clipboard.HasFormat(CF_DIB) then
  begin
    OpenClipboard(0);
    try
      ClipboardHandle := GetClipboardData(CF_DIB);
      if ClipboardHandle <> 0 then
      begin
        Src := GlobalLock(ClipboardHandle);
        try
          Size := GlobalSize(ClipboardHandle);
          if Size > 0 then
          begin
            ATarget.WriteBuffer(Src^, Size);
            ATarget.Position := 0;
            Result := True;
          end
          else
            Result := False;
        finally
          GlobalUnlock(ClipboardHandle);
        end;
      end
      else
        Result := False;
    finally
      CloseClipboard;
    end;
  end
  else
    Result := False;
end;

procedure TForm290.FormCreate(Sender: TObject);
var
  Data: TMemoryStream;
begin
  Data := TMemoryStream.Create;
  try
    if GetClipboardDIBData(Data) then
      Data.SaveToFile('c:\temp\clipboarddata.bin');
  finally
    Data.Free;
  end;
end;

Amateurprofi 8. Apr 2025 23:27

AW: Bitmap aus Clipboard laden
 
Liste der Anhänge anzeigen (Anzahl: 1)
@jaenicke

Vielen Dank, Sebastian.

Zu "Solch eine Funktion hat das Tool gar nicht. ...":
Ich bin eigentlich recht vorsichtig mit dem Klicken, möchte das aber nicht ausschließen.
Werde es also noch einmal versuchen.

Zu "Paint legt in die Zwischenablage unter anderem CF_DIB und PNG ab, aber nicht CF_Bitmap."
Doch, auch CF_Bitmap ist enthalten (Siehe Bild_4).
Ups, gerade sehe ich das CF_Bitmap zwar vorhanden ist, aber mit Size=0.

Zu "... aber dann hast du auch wirklich nur die reinen Bildinformationen":
Ja, genau das möchte ich ja auch.
Ich möchte einfach wissen, welche Daten da wirklich stehen.
Vielleicht finde ich ja heraus, was der Grund für die verfälschten Farben ist.
Vielen Dank auch für die Programm-Codes. Werde ich mir im Laufe der Woche anschauen.

Sinspin 9. Apr 2025 13:16

AW: Bitmap aus Clipboard laden
 
Zitat:

Zitat von Amateurprofi (Beitrag 1547924)
Zitat:

Zitat von Sinspin (Beitrag 1547920)
Das geht aber auch in Delphi auch. Nur halt eventuell nicht mit Canvas, sondern der Gr32 oder was in der Art.

Das geht auch mit Canvas, aber warum erst eine Prozedur schreiben, wenn Paint das Zuschneiden von Bildern perfekt macht?
Ich könnte auch alles mit Buntstiften abmalen. Will ich aber nicht.

Weil es einfacher ist eine Bmp-Datei mit einem externen Programm zu öffnen, darin mit dem externen Programm rumzumalen, es in die Zwischenablage zu kopieren und von dort dann endlich in Delphi zu öffnen?
Das sind keine Buntstifte, das sind Tanklaster voller Farbe.

Abgesehen davon dass Du nicht steuern kannst wie Paint das Bild in die Zwischenablage schreibt, können auch alle Programm die eine Zwischenablage implementiert haben sich das Bild "heimlich" ziehen. Inclusive offene Remote Sessions (soweit nicht deaktiviert).

Amateurprofi 9. Apr 2025 23:01

AW: Bitmap aus Clipboard laden
 
Zitat:

Zitat von Sinspin (Beitrag 1547949)
Zitat:

Zitat von Amateurprofi (Beitrag 1547924)
Zitat:

Zitat von Sinspin (Beitrag 1547920)
Das geht aber auch in Delphi auch. Nur halt eventuell nicht mit Canvas, sondern der Gr32 oder was in der Art.

Das geht auch mit Canvas, aber warum erst eine Prozedur schreiben, wenn Paint das Zuschneiden von Bildern perfekt macht?
Ich könnte auch alles mit Buntstiften abmalen. Will ich aber nicht.

Weil es einfacher ist eine Bmp-Datei mit einem externen Programm zu öffnen, darin mit dem externen Programm rumzumalen, es in die Zwischenablage zu kopieren und von dort dann endlich in Delphi zu öffnen?
Das sind keine Buntstifte, das sind Tanklaster voller Farbe.

Abgesehen davon dass Du nicht steuern kannst wie Paint das Bild in die Zwischenablage schreibt, können auch alle Programm die eine Zwischenablage implementiert haben sich das Bild "heimlich" ziehen. Inclusive offene Remote Sessions (soweit nicht deaktiviert).

Zu "Weil es einfacher ist ..."
Ja

Zu "dass Du nicht steuern kannst wie Paint das Bild in die Zwischenablage schreibt"
Ich bin dabei das herauszufinden.

Zu "können auch alle Programm"
Hab ich nichts dagegen.

Amateurprofi 18. Apr 2025 23:38

AW: Bitmap aus Clipboard laden
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe jetzt geprüft welche Daten unter CF_DIB im Clipboard stehen, nachdem eine .bmp-Datei mit dem Pixelformat pf8bit mit Paint geöffnet wurde und mit Ctrl-A und Ctrl-C ins Clipboard kopiert wurde.

In Kürze (Komplette Auswertung im Anhang)
Im Clipboard stehen unter CF_DIB folgende Daten:
1) Der komplette BitmapInfoHeader (40 Bytes).
Die Daten sind korrekt.
2) Die Palette mit 256 Einträgen. (1024 Bytes).
Warum eine Palette mit 256 Einträgen gespeichert wird, wenn nur 26 verschiedene Farben in der Bitmap enthalten sind, erschließt sich mir nicht.
Von den 26 Farben der Bitmap sind nur 4 in der Palette enthalten-
3) Die Farbinformationen (Indizes in die Palette) (256 Bytes).
4) Daten, deren Bedeutung (mir) unklar sind. (2776 Bytes).

Wenn ich die Datei mit Photoshop üffne und ins Clipboard kopiere sieht das anders aus,
Dann sind unter CF_DIB gespeichert:
1) Der komplette BitmapInfoHeader (40 Bytes).
Anders als bei Paint sind biClrUsed und biClrImportant = 239 (statt 0 bei Paint).
2) Die Palette mit 239 Einträgen. (956 Bytes).
Warum die Palette gerade 239 Einträge hat, ist mir nicht klar, denn 26 Einträge wären ausreichend.
3) Die Farbinformationen (Indizes in die Palette) (256 Bytes).
Wenn ich dann z.B. in Paint ein Paste mache, wird das Bild korrekt angezeigt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:50 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