Forum > BGRABitmap and LazPaint
How to get xlib's window icon using BGRABitmap?
AFFRIZA 亜風実:
So, long story short, I'm interested to make my own docked taskbar for KDE :-[
I tried to C++ mimic code from here to read the icon: https://stackoverflow.com/questions/55413341/get-applications-icon-using-xlib
and the result is like this:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function ReadBitmap(Val: PByte; W, H, Size: integer): TBGRABitmap;var bmp: TBGRABitmap; a, r, g, b: byte; argb: PByte; x, y: Integer;begin bmp := TBGRABitmap.Create(w, h); argb := Val; for y := 0 to H -1 do begin for x := 0 to W -1 do begin a := argb[3]; r := argb[2] * a div 255; g := argb[1] * a div 255; b := argb[0] * a div 255; //bmp.Canvas.DrawPixel(x, y, FPImage.FPColor(r, g, b, a)); bmp.DrawPixel(x, y, BGRA(r, g, b, a)); Inc(argb, 4); end; end; Result := bmp;end; function TWindowData.GetIcon: TBGRABitmap;var ActualTypeReturn: TAtom; ActualFormatReturn: LongInt; NItemsReturn, BytesAfterReturn: Cardinal; Ptr: PByte; IconAtom: TAtom; PropResult: boolean; i: integer; Width, Height, Size: Cardinal;begin Width := 0; Height := 0; IconAtom := XInternAtom(fXWindowList.Display, '_NET_WM_ICON', LongBool(1)); PropResult := XGetWindowProperty(fXWindowList.Display, fWindow, IconAtom, 0, 1, 0, AnyPropertyType, @ActualTypeReturn, @ActualFormatReturn, @NItemsReturn, @BytesAfterReturn, @Ptr) = Success; if PropResult then Width := PCardinal(Ptr)^; if Assigned(Ptr) then XFree(Ptr); PropResult := XGetWindowProperty(fXWindowList.Display, fWindow, IconAtom, 1, 1, 0, AnyPropertyType, @ActualTypeReturn, @ActualFormatReturn, @NItemsReturn, @BytesAfterReturn, @Ptr) = Success; if PropResult then Height := PCardinal(Ptr)^; Size := Width * Height; if Assigned(Ptr) then XFree(Ptr); PropResult := XGetWindowProperty(fXWindowList.Display, fWindow, IconAtom, 2, Size, 0, AnyPropertyType, @ActualTypeReturn, @ActualFormatReturn, @NItemsReturn, @BytesAfterReturn, @Ptr) = Success; if PropResult then begin Result := ReadBitmap(Ptr, Width, Height, Size); end; if Assigned(Ptr) then XFree(Ptr);end;
The icons is kind of broken in the result (in the attachment). Maybe someone can help? :D
I really want to attach the full source but it's become big, so I put that in a Github:
https://github.com/kirana-a2district/samarinda-dock
https://github.com/kirana-a2district/kiranacore-pkg
AFFRIZA 亜風実:
I just modified the code to:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function ReadBitmap(Val: PByte; W, H, Size: integer): TBGRABitmap;var bmp: TBGRABitmap; a, r, g, b: byte; argb: PByte; i, f, x, y: Integer; imgBuffer: TBytes;begin bmp := TBGRABitmap.Create(w, h); SetLength(imgBuffer, Length(TBytes(Val)) div 2); argb := PByte(imgBuffer); i := 0; while i < Length(TBytes(Val)) div 2 do begin argb[i] := Val[(i*2)]; argb[i+1] := Val[(i*2)+1]; argb[i+2] := Val[(i*2)+2]; argb[i+3] := Val[(i*2)+3]; i += 4; end; for y := 0 to H -1 do begin for x := 0 to W -1 do begin a := argb[3]; r := argb[2]; g := argb[1]; b := argb[0]; //bmp.Canvas.DrawPixel(x, y, FPImage.FPColor(r, g, b, a)); bmp.DrawPixel(x, y, BGRA(r, g, b, a)); Inc(argb, 4); end; end; Result := bmp;end;
The colors is much better now :D
But the icons are still has distortion thingy %)
Roland57:
Hello! Very interesting stuff.
Unfortunately, I get an access violation at application start. (I had to remove the reference to qt5 unit. My Lazarus is gtk2.)
AFFRIZA 亜風実:
--- Quote from: Roland57 on June 14, 2022, 05:44:19 pm ---Hello! Very interesting stuff.
Unfortunately, I get an access violation at application start. (I had to remove the reference to qt5 unit. My Lazarus is gtk2.)
--- End quote ---
Sorry but it supposed to run under Qt5, since I wrote this for KDE, and also... I need the Qt5's translucent window thing to make the form transparent without affecting the components inside.
If you want, maybe I can help you to setup the Lazarus to run with Qt5. :D
circular:
Ok so each pixel is represented by 8 bytes. Well 4 bytes padded with 4 more bytes if the CPU is 64bits.
First version was almost correct except step between values.
I suppose the following would work as well:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function ReadBitmap(Val: PByte; W, H, Size: integer): TBGRABitmap;var bmp: TBGRABitmap; argb: PByte; pdest: PBGRAPixel; x, y: Integer;begin bmp := TBGRABitmap.Create(w, h); argb := Val; for y := 0 to H -1 do begin pdest := bmp.ScanLine[y]; for x := 0 to W -1 do begin pdest^.alpha := argb[3]; pdest^.red := argb[2]; pdest^.green := argb[1]; pdest^.blue := argb[0]; Inc(argb, {$IFDEF CPU64}8{$ELSE}4{$ENDIF}); inc(pdest); end; end; bmp.InvalidateBitmap; Result := bmp;end;
I am not sure about the distortion but maybe you can assume that alpha is in fact 255 when alpha is zero and red/green/blue are non zero.
Navigation
[0] Message Index
[#] Next page