GTK/GDK Clipboard

artelogic
Beiträge: 15
Registriert: Mi 20. Apr 2022, 12:42

GTK/GDK Clipboard

Beitrag von artelogic »

Gibt es eine Möglichkeit herauszufinden, ob im CB eine 32bit-Bitmap zum Pasten zur Verfügung steht?

Gibt es überhaupt eine Liste der verschiedenen Formate?

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: GTK/GDK Clipboard

Beitrag von theo »

Soweit ich weiss, steht das Pixelformat nicht als Extra-Information im CB.
Da muss man das Bild schon laden.

Code: Alles auswählen

var
  ABmp: TBitmap;
begin
  if Clipboard.HasFormat(CF_Bitmap) then
  begin
    ABmp := TBitmap.Create;
    ABmp.LoadFromClipboardFormat(CF_Bitmap);
    ShowMessage('Bitmap Pixelformat: ' + IntToStr(PIXELFORMAT_BPP[ABmp.PixelFormat]));
    ABmp.Free;
  end;
end; 
Man könnte auch nur den BITMAPINFOHEADER aus dem Stream lesen, dann wird es aber etwas komplizierter.

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: GTK/GDK Clipboard

Beitrag von Winni »

Hi!

Details zur Clipboard-Arie gibt's hier:

https://wiki.lazarus.freepascal.org/Clipboard/de

Man kann auch selbst Clipboard-Formate anlegen, was z.B. für PNGs notwendig ist:

Code: Alles auswählen

pngClipboardFormat := RegisterClipboardFormat({$IfDef WINDOWS}'PNG'{$Else}{$IfDef DARWIN}'public.png'{$Else}'image/png'{$EndIf}{$EndIf});
Irgendwo in den BGRAbitmap-Units gefunden

Winni

wp_xyz
Beiträge: 4885
Registriert: Fr 8. Apr 2011, 09:01

Re: GTK/GDK Clipboard

Beitrag von wp_xyz »

Das bmp-Format ist nicht kompliziert und man findet die Header-Records nach einer schnellen Suche im Internet. Oder noch einfacher: In der fpc-Unit bmpcomn stehen sie schon fertig zur Verwendung. Damit kann man dann sowas wie die folgende Funktion schreiben:

Code: Alles auswählen

uses
  bmpcomn;
  
function GetBitmapInfo(AStream: TStream; out AWidth, AHeight, ABitsPerPixel: Integer): String;
var
  filehdr: TBitmapFileHeader;
  infohdr: TBitmapInfoHeader;
  n: Integer;
begin
  AWidth := 0;
  AHeight := 0;
  ABitsPerPixel := 0;

  AStream.Position := 0;
  n := AStream.Read(filehdr{%H-}, SizeOf(filehdr));
  if n <> SizeOf(filehdr) then
  begin
    Result := 'Defekter Datei-Header.';
    exit;
  end;
  if filehdr.bfType <> BMmagic then
  begin
    Result := 'Keine BMP-Dateistruktur.';
    exit;
  end;
  n := AStream.Read(infohdr{%H-}, SizeOf(infohdr));
  if n <> SizeOf(infohdr) then
  begin
    Result := 'Defekte Header-Daten.';
    exit;
  end;
  AWidth := infoHdr.Width;
  AHeight := infoHdr.Height;
  ABitsPerPixel := infoHdr.BitCount;
  Result := '';
end;
Und das wird dann etwa so angewendet:

Code: Alles auswählen

uses
  Clipbrd;
  
procedure TForm1.Button1Click(Sender: TObject);
var
  stream: TMemoryStream;
  err: String;
  w, h, bpp: Integer;
begin
  stream := TMemoryStream.Create;
  try
    if Clipboard.GetFormat(CF_BITMAP, stream) then
    begin
      err := GetBitmapInfo(stream, w, h, bpp);
      if err = '' then
        ShowMessage(Format(
          'In der Zwischenablage befindet sich zur Zeit ein Bitmap mit %d Bits pro Pixel, Breite %d, Höhe %d.', 
          [bpp, w, h])
        )
      else
        ShowMessage('Es scheint sich ein Bitmap in der Zwischenablage zu befinden, aber es tritt der folgende Fehler auf:' + Lineending + err);
    end else
      ShowMessage('In der Zwischenablage befindet sich aktuell kein Bitmap.');
  finally
    stream.Free;
  end;
end;

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: GTK/GDK Clipboard

Beitrag von theo »

wp_xyz hat geschrieben:
So 22. Mai 2022, 12:10
Das bmp-Format ist nicht kompliziert und man findet die Header-Records nach einer schnellen Suche im Internet. Oder noch einfacher: In der fpc-Unit bmpcomn stehen sie schon fertig zur Verwendung.
"Kompliziert" habe ich nicht gesagt, aber "etwas komplizierter" ist es schon. :wink:
Vor allem wusste ich nicht, worum es dem OP genau geht.
Wenn er sich vorstellt, eine Liste mit verschiedenen Farbtiefen zur Auswahl im Clipboard zu haben, dann wäre mir das nicht bekannt.

tagBITMAPINFOHEADER / TBitmapInfoHeader / BITMAPINFOHEADER findet man übrigens auch in LCLType.

artelogic
Beiträge: 15
Registriert: Mi 20. Apr 2022, 12:42

Re: GTK/GDK Clipboard

Beitrag von artelogic »


wp_xyz
Beiträge: 4885
Registriert: Fr 8. Apr 2011, 09:01

Re: GTK/GDK Clipboard

Beitrag von wp_xyz »

Einige dieser CF_* Konstanten sind cross-platform, siehe Unit Clipbrd. Und meinen obigen Code habe ich natürlich auch unter Linux getestet und kein Problem festgestellt.

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: GTK/GDK Clipboard

Beitrag von Winni »

Hi!

Vordefiniert sind in LCLType für alle Betriebssystem schon mal folgende Formate:

Code: Alles auswählen

type
  TPredefinedClipboardFormat = (
      pcfText,
      pcfBitmap,
      pcfPixmap,
      pcfIcon,
      pcfPicture,
      pcfMetaFilePict,
      pcfObject,
      pcfComponent,
      pcfCustomData
    );
Den Rest muss Du Dir anscheinend selbst zusammen bauen.

Winni

artelogic
Beiträge: 15
Registriert: Mi 20. Apr 2022, 12:42

Re: GTK/GDK Clipboard

Beitrag von artelogic »

theo hat geschrieben:
So 22. Mai 2022, 12:25
wp_xyz hat geschrieben:
So 22. Mai 2022, 12:10
Vor allem wusste ich nicht, worum es dem OP genau geht.
Wollte ja nur hierauf noch antworten.

artelogic
Beiträge: 15
Registriert: Mi 20. Apr 2022, 12:42

Re: GTK/GDK Clipboard

Beitrag von artelogic »

Und suche insbesondere den hier: CF_DIBV5

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: GTK/GDK Clipboard

Beitrag von theo »

Naja, es geht hier eher um X11, weniger um GTK im Speziellen.
Wenn ich z.B. meinen Avatar hier kopiere, dann gibt mir "xclip -o -t TARGETS" aus:
TIMESTAMP
TARGETS
MULTIPLE
text/html
text/_moz_htmlinfo
text/_moz_htmlcontext
image/png
image/bmp
image/x-bmp
image/x-MS-bmp
image/x-icon
image/x-ico
image/x-win-bitmap
image/vnd.microsoft.icon
application/ico
image/ico
image/icon
text/ico
image/jpeg
image/tiff
Das Gleiche gibt es so:

Code: Alles auswählen

  Clipboard.SupportedFormats(Memo1.Lines);         
Ob das viel hilft?

wp_xyz
Beiträge: 4885
Registriert: Fr 8. Apr 2011, 09:01

Re: GTK/GDK Clipboard

Beitrag von wp_xyz »

Du könntest z.B. mit Clipboard.FindFormatID jeden in Frage kommenden MIME-Type aus theo's Liste (wenn 'image/' vorne steht) prüfen, ob es sich um das gewünschte Format handelt. Beispiel: fmt := Clipboard.FindFormatID('image/x-bmp'); wenn dieses Format vorhanden ist, wäre fmt <> 0 und könnte in der schon oben verwendeten Methode Clipboard.GetFormat als FormatID (statt CF_BITMAP) verwendet werden, um den zugehörigen Stream auszulesen. Damit könntest du den BitmapInfo-Header lesen und die BitsPerPixel entnehmen.

Aber vielleicht ist eines dieser 'image/<irgendwas>' auch schon definitionsgemäß ein 32-bit Bitmap, damit wäre die Suche nach dem FindFormatID schon beendet.

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: GTK/GDK Clipboard

Beitrag von Winni »

Hi!

Die späte Einführung von CF_DIBV5 in der BMP-Struktur war der Versuch von M$ einen Alpha-Kanal - also Transparenz - mit BMP-Dateien zu ermöglichen, also von 24 Bit auf 32 zu erweitern. Das Format ist extrem ungebräuchlich und selten anzutreffen.

Ich hab vor einiger Zeit den Versuch gestartet, CF_DIBV5 als Clipboard Format zu installieren und bin gescheitert. Der Versuch fand auch allerdings unter Linux statt.

Mein Workaround: PNG benutzen (s.o.)

Winni

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: GTK/GDK Clipboard

Beitrag von theo »

wp_xyz hat geschrieben:
So 22. Mai 2022, 13:34
Du könntest z.B. mit Clipboard.FindFormatID jeden in Frage kommenden MIME-Type aus theo's Liste (wenn 'image/' vorne steht) prüfen, ob es sich um das gewünschte Format handelt.
Bin nicht sicher. Ich gehe davon aus, dass alle bmp/bitmap MIME-Typen der Liste nur Aliase sind und auf die gleichen Daten verweisen.
Also vermute ich, dass das alles auf CF_BITMAP hinausläuft.

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: GTK/GDK Clipboard

Beitrag von theo »

Winni hat geschrieben:
So 22. Mai 2022, 13:57
also von 24 Bit auf 32 zu erweitern. Das Format ist extrem ungebräuchlich und selten anzutreffen.
Das sehe ich auch so. Ich glaube eher nicht, dass eine Linux Anwendung ein 32bit-Bitmap ins Clipboard legt, jedenfalls nicht implizit.

Antworten