Questions regarding this lib
elderapo opened this issue · 9 comments
Hello!
When I was checking out examples in this repo I came up with an idea of making software similar to LightShot but for Linux.
In this example we can see how to render current "screen dump" to other window. If I am not mistaken the first argument passed to X.getImage
is supposed to be format
which happens to be set to 2 in given example. I didn't really know what it meant so I searched this repo and found this line. Unfortunately if I set format to 0 (bitmap according to previous link) in X.getImage
I get this error:
{ Error: Bad param value
at ReadFixedRequest.callback (/home/elderapo/nodejs/node-x11/lib/xcore.js:465:29)
at ReadFixedRequest.execute (/home/elderapo/nodejs/node-x11/lib/unpackstream.js:41:10)
at UnpackStream.resume (/home/elderapo/nodejs/node-x11/lib/unpackstream.js:165:30)
at UnpackStream.write (/home/elderapo/nodejs/node-x11/lib/unpackstream.js:102:10)
at Socket.<anonymous> (/home/elderapo/nodejs/node-x11/lib/xcore.js:88:21)
at emitOne (events.js:115:13)
at Socket.emit (events.js:210:7)
at addChunk (_stream_readable.js:266:12)
at readableAddChunk (_stream_readable.js:253:11)
at Socket.Readable.push (_stream_readable.js:211:10)
error: 2,
seq: 7,
message: 'Bad param value',
badParam: 0,
minorOpcode: 0,
majorOpcode: 73 }
I guess this error means that 0 (bitmap) is incorrect value and that if I want to get bitmap I should convert ZPixmap
to bitmap. If so any tips how I can achive that?
Also I was wondering if it's possible to get color of the pixel at given coordinates in x window. I found some c++ snippets using XGetImage
and XGetPixel
to achieve that but I couldn't find anything about GetPixel
in this repo.
In X11 terms, a bitmap is an image represented by 1 bit per pixel, which is probably not what you want. The ZPixmap captured by X.GetImage
is in the format BGRA, so it should be pretty simple to loop through image.data
and convert to RGBA or RGB, ready for saving as a PNG, putting into a canvas
element, etc.
Also I was wondering if it's possible to get color of the pixel at given coordinates in x window. I found some c++ snippets using XGetImage and XGetPixel to achieve that but I couldn't find anything about GetPixel in this repo.
This library tries to implement x11 protocol, and there is no 'GetPixel' request in the protocol ( though you can get 1x1 rectangle with XGetImage. When you do XGetPixel with xlib it probably grabs some area using GetImage
request, stores it locally and then retrieves pixel value from that data
Thanks for the answers!
I managed to save screenshot to file using following code. It will suit "LightShot clone" needs.
I also noticed that X.GetImage
is kind of slow. It takes ~70 ms to get 1920x1080 image (X.GetImage
takes that much - not conversion from BGRA to RGBA). Is there anything I can do to easly improve X.GetImage
performance?
You can try to use MIT-SHM extension. The idea is that if server and client share same memory you can avoid copying large amount of data over network ( 1920x1080x32bit = 6 MBytes, 70 ms not that bad actually for this amount )
Can't remember what's the status of mit-shm extension here. I did some research a while ago but as far as I can remember not finished implementation. Would be good to add it
https://www.npmjs.com/package/nodeshm
https://www.x.org/releases/X11R7.7/doc/xextproto/shm.txt
You can try to use MIT-SHM extension. The idea is that if server and client share same memory you can avoid copying large amount of data over network ( 1920x1080x32bit = 6 MBytes, 70 ms not that bad actually for this amount )
But in a C program XGetImage
takes about 7ms
This client is not perfect and adds some overhead. I'm thinking about a complete rewrite to make use modern stream and Buffer helpers
If you use the shared memory extension you can do a screenshot in 0.000029ms though you need to use native code for that
Never mind, it's actually 0.023ms. Still a big improvement though