Skip to content

Instantly share code, notes, and snippets.

@pnck
Created April 8, 2018 06:23
Show Gist options
  • Save pnck/564eb2fa64ef91ab9ba1032a085e61f9 to your computer and use it in GitHub Desktop.
Save pnck/564eb2fa64ef91ab9ba1032a085e61f9 to your computer and use it in GitHub Desktop.
capture screen from /dev/fb0
#!/usr/bin/python2
FBIOGET_VSCREENINFO = 0x4600
FBIOPUT_VSCREENINFO = 0x4601
FBIOGET_FSCREENINFO = 0x4602
FBIOGETCMAP = 0x4604
FBIOPUTCMAP = 0x4605
FBIOPAN_DISPLAY = 0x4606
BI_BITFIELDS = 3
BI_RAW = 0
__comment__ = '''
struct fb_bitfield {
__u32 offset; /* beginning of bitfield */
__u32 length; /* length of bitfield */
__u32 msb_right; /* != 0 : Most significant bit is */
/* right */
'''
import os
import sys
import struct
from fcntl import ioctl
def usage():
print('nothing yet..')
pass
def convert(fname):
from PIL import Image
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
with Image.open(fname) as f:
print('converting ' + fname + ' to png...')
f.save(fname[:-3] + 'png')
f.close()
print('done.')
os.unlink(fname)
def cap_fb(fname):
with open('/dev/fb0') as f:
l = list(struct.unpack(
'I' * 40, ioctl(f, FBIOGET_VSCREENINFO, '\x00' * 160)))
w = l[0]
h = l[1]
vw = l[2]
vh = l[3]
xo = l[4]
yo = l[5]
bitdepth = l[6]
bytesofpixel = bitdepth / 8
is_color = l[7]
# [8:11],[11:14],[14:17],[17:20]
rgba_bitfields = zip(*[iter(l[8:20])] * 3)
print 'fb layout:', l[:7]
ones = int('1' * bitdepth, 2)
masks = struct.pack(
'4I', *[(ones & (~(ones << bitfield[1])) << bitfield[0]) for bitfield in rgba_bitfields])
fb_memsize = vw * vh * bytesofpixel
raw = f.read()
d = raw[:fb_memsize]
#d = f.read(fb_memsize)
#open('fb_raw.save', 'wb').write(raw)
dd = [d[i * vw * bytesofpixel:(i + 1) * vw * bytesofpixel]
for i in range(vh)] # split to vh rows
dd = dd[yo:h + yo] # chop y
d = [row[xo * bytesofpixel:(w + xo) * bytesofpixel]
for row in dd] # chop x
d = ''.join(d)
bmp_sign = 'BM'
bmp_size = struct.pack('I', 0)
bmp_reserved = '\x00' * 4
bmp_dataoff = struct.pack('I', 0)
#-----------14--------------------
bmp_szinfohdr = struct.pack('I', 40)
bmp_w = struct.pack('I', w)
bmp_h = struct.pack('i', -h) # so i dont have to reverse all data
bmp_planes = struct.pack('h', 1)
bmp_bitcount = struct.pack('h', bitdepth)
# define BI_BITFIELDS 3 /* RGB bitmap with RGB masks */
bmp_bicompress = struct.pack(
'I', {24: BI_RAW, 32: BI_RAW}.get(bitdepth, BI_BITFIELDS))
bmp_imsize = struct.pack('I', fb_memsize)
bmp_xresolution = struct.pack('I', 0)
bmp_yresolution = struct.pack('I', 0)
bmp_colorused = struct.pack('I', 0)
bmp_colorsimportant = struct.pack('I', 0)
#--------------40----------------------
#--------------mask=4*4--------------
bmp_raw_h1 = bmp_sign + bmp_size + bmp_reserved + bmp_dataoff
bmp_raw_h2 = bmp_szinfohdr + bmp_w + bmp_h + bmp_planes + bmp_bitcount + bmp_bicompress + \
bmp_imsize + bmp_xresolution + bmp_yresolution + \
bmp_colorused + bmp_colorsimportant
if bitdepth not in (24, 32):
bmp_raw_h2 += masks
# header filled
# process alignment
align = w % 4
if bitdepth != 32 and align: # dont need when bitdepth==32
align = 4 - align
splits = [d[0 + i:w + i] for i in range(0, len(d), w)]
d = ''.join([p + '\x00' * align for p in splits])
# re-calc size & offsets
bmp_dataoff = struct.pack('I', len(bmp_raw_h1) + len(bmp_raw_h2))
bmp_size = struct.pack('I', len(bmp_raw_h1) + len(bmp_raw_h2) + len(d))
bmp_raw_h1 = bmp_sign + bmp_size + bmp_reserved + bmp_dataoff
bmp_raw = bmp_raw_h1 + bmp_raw_h2 + d
print('saving: ' + fname)
with open(fname, 'wb') as ff:
ff.write(bmp_raw)
print('..OK')
try:
from PIL import Image
convert(fname)
except:
pass
if __name__ == '__main__':
if len(sys.argv) <= 1: # scrshot.py
cap_fb('scrshot_last.bmp')
elif sys.argv[1] == 'convert':
if len(sys.argv) < 3: # scrshot.py convert
usage()
else: # scrshot.py convert xx xxx xxx
args = sys.argv[2:]
for fname in args:
convert(fname)
else: # scrshot.py xxx
fname = sys.argv[1]
if sys.argv[1][-3:].lower() != 'bmp':
fname += '.bmp'
if os.path.exists(fname):
fname = fname[:-4] + '_2.bmp'
while os.path.exists(fname) :
fname = fname[:-4] + '_2.bmp'
cap_fb(fname)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment