fbgrab output gives blank png - linux

Trying to get screenshot using fbgrab -d /dev/fb0 img0.png but it always outputs a blank image.
Am I missing something here?
The captured png has entire range with 255 values as I can see from histogram.
Environment:
Linux based custom OS built using buildroot running on i.MX6q based embedded custom board.
X.org is not enabled.
2 framebuffers(/dev/fb0, /dev/fb1) each being updated by different programs using QT eglfs.
root#hostname:/root# fbgrab -v -z 9 -d /dev/fb0 img0.png
frame buffer fixed info:
id: "DISP3 BG - DI1"
type: packed pixels
line length: 7680 bytes (1920 pixels)
frame buffer variable info:
resolution: 1920x1080
virtual resolution: 1920x4352
offset: 0x3264
bits_per_pixel: 32
grayscale: false
red: offset: 16, length: 8, msb_right: 0
green: offset: 8, length: 8, msb_right: 0
blue: offset: 0, length: 8, msb_right: 0
alpha: offset: 24, length: 8, msb_right: 0
pixel format: non-standard
Resolution: 1920x1080 depth 32
Converting image from 32
Now writing PNG file (compression 9)
root#hostname:/root# fbgrab -v -z 9 -d /dev/fb1 img1.png
frame buffer fixed info:
id: "DISP3 FG"
type: packed pixels
line length: 7680 bytes (1920 pixels)
frame buffer variable info:
resolution: 1920x1080
virtual resolution: 1920x1080
offset: 0x0
bits_per_pixel: 32
grayscale: false
red: offset: 16, length: 8, msb_right: 0
green: offset: 8, length: 8, msb_right: 0
blue: offset: 0, length: 8, msb_right: 0
alpha: offset: 24, length: 8, msb_right: 0
pixel format: standard
Resolution: 1920x1080 depth 32
Converting image from 32
Now writing PNG file (compression 9)
Tried fbdump using fbdump > grab.ppm the output is different but not close to what is on the screen. I do not have ppmtopng package installed to use fbdump | ppmtopng > grab.png

Related

Python - Multiple images to multilayered .xcf

I have three PIL images of the same size in RAM (no disk here). They represent different frequencies (details, shadow, mask).
Is it possible to overlay these images into a .xcf file to further process them by hand in gimp? If so, can the opacity of the layers be controlled before saving the image?
I'm ideally looking for a python solution.
Not certain what GIMP expects, but this might get you started as a multi-layer TIFF with varying opacities:
#!/usr/bin/env python3
import numpy as np
from PIL import Image
w, h = 400, 400
# Our layers to write to output file
layers = []
# Make layer 0 - 400x400 RGBA with red square, A=64
im = np.full((w,h,4), [0,0,0,64], np.uint8)
im[10:110, 10:110, :3] = [255,0,0]
layers.append(Image.fromarray(im))
# Make layer 1 - 400x400 RGBA with green square, A=128
im = np.full((w,h,4), [0,0,0,128], np.uint8)
im[20:120, 20:120, :3] = [0,255,0]
layers.append(Image.fromarray(im))
# Make layer 2 - 400x400 RGBA with blue square, A=192
im = np.full((w,h,4), [0,0,0,192], np.uint8)
im[30:130, 30:130, :3] = [0,0,255]
layers.append(Image.fromarray(im))
# Save as multi-layer TIFF with PIL
layers[0].save('result.tif', save_all=True, append_images=layers[1:], compression='tiff_lzw')
The Preview app on macOS displays it like this - hopefully you can see the red at least is more transparent, or less vibrant:
tiffinfo perceives it like this:
TIFF Directory at offset 0x9740 (260c)
Image Width: 400 Image Length: 400
Bits/Sample: 8
Compression Scheme: LZW
Photometric Interpretation: RGB color
Extra Samples: 1<unassoc-alpha>
Samples/Pixel: 4
Rows/Strip: 40
Planar Configuration: single image plane
TIFF Directory at offset 0x20096 (4e80)
Image Width: 400 Image Length: 400
Bits/Sample: 8
Compression Scheme: LZW
Photometric Interpretation: RGB color
Extra Samples: 1<unassoc-alpha>
Samples/Pixel: 4
Rows/Strip: 40
Planar Configuration: single image plane
TIFF Directory at offset 0x30506 (772a)
Image Width: 400 Image Length: 400
Bits/Sample: 8
Compression Scheme: LZW
Photometric Interpretation: RGB color
Extra Samples: 1<unassoc-alpha>
Samples/Pixel: 4
Rows/Strip: 40
Planar Configuration: single image plane

Why does librosa load change the flac file?

I have an original file 0.flac which I just open with librosa and then save with SoundFile as 1.flac:
import soundfile as sf
import librosa
in_path = "0.flac"
out_path = "1.flac"
sampling_rate = 16000
wav, source_sampling_rate = librosa.load(in_path, sr=None)
assert(source_sampling_rate == sampling_rate)
# 16bit -> PCM_16
sf.write(out_path, wav, sampling_rate, format='flac', subtype='PCM_16')
However the file size and file itself seems to be changed:
User#User-MacBook-Pro:~/check_librosa$ metaflac --list 0.flac
METADATA block #0
type: 0 (STREAMINFO)
is last: false
length: 34
minimum blocksize: 4096 samples
maximum blocksize: 4096 samples
minimum framesize: 107 bytes
maximum framesize: 5961 bytes
sample_rate: 16000 Hz
channels: 1
bits-per-sample: 16
total samples: 225360
MD5 signature: 41222a894966327db4f89afa74e5e1a1
METADATA block #1
type: 3 (SEEKTABLE)
is last: false
length: 36
seek points: 2
point 0: sample_number=0, stream_offset=0, frame_samples=4096
point 1: sample_number=159744, stream_offset=170830, frame_samples=4096
METADATA block #2
type: 4 (VORBIS_COMMENT)
is last: false
length: 40
vendor string: reference libFLAC 1.2.1 20070917
comments: 0
METADATA block #3
type: 1 (PADDING)
is last: true
length: 8192
User#User-MacBook-Pro:~/check_librosa$ metaflac --list 1.flac
METADATA block #0
type: 0 (STREAMINFO)
is last: false
length: 34
minimum blocksize: 4096 samples
maximum blocksize: 4096 samples
minimum framesize: 107 bytes
maximum framesize: 6040 bytes
sample_rate: 16000 Hz
channels: 1
bits-per-sample: 16
total samples: 225360
MD5 signature: 41222a894966327db4f89afa74e5e1a1
METADATA block #1
type: 4 (VORBIS_COMMENT)
is last: true
length: 40
vendor string: reference libFLAC 1.3.3 20190804
comments: 0
There are less metadata blocks and the maximum framesize is different.
What could be the reason for this? Is loading the file via librosa lossy?

How to store a segmented image as thematic image as opposed to continuous image

I have a result of image segmentation image array as image(values as predicted class).when i save this image i get continuous layer type . But what i want is thematic layer type instead.
What function or parameters i should use to save this image as thematic(in .tif format)
eg. a 3x3 image looks like
[2,3,1
0,1,2
3,1,2]
instead of pixel values like
[255,192,64
0,64,128
128,192,64]
I want histogram to read from 0-3. Instead histogram is in the range(0-256) for first 3x3 example image.
I am using tifffile to write in .tif format
pred = numpy.argmax(ypreds, axis = 2)
tifffile.imwrite("pred1.tif", pred)
This code seems to save the values as you require:
import numpy as np
import tifffile
# Create representative image
y = np.random.randint(0,4,size=(3,3),dtype=np.uint8)
# Mine looks like this
# array([[1, 3, 3],
# [0, 2, 3],
# [1, 0, 0]], dtype=uint8)
# Save as TIFF
tifffile.imsave("pred1.tif",y)
Now check contents with ImageMagick and values and histogram appear to match data:
magick identify -verbose pred1.tif
Image: pred1.tif
Format: TIFF (Tagged Image File Format)
Mime type: image/tiff
Class: DirectClass
Geometry: 3x3+0+0
Resolution: 1x1
Print size: 3x3
Units: Undefined
Colorspace: Gray
Type: Grayscale
Endianess: LSB
Depth: 8-bit
Channel depth:
Gray: 8-bit
Channel statistics:
Pixels: 9
Gray:
min: 0 (0) <--- matches image
max: 3 (0.0117647) <--- matches image
mean: 1.44444 (0.00566449)
standard deviation: 1.33333 (0.00522876)
kurtosis: -1.91725
skewness: 0.105324
entropy: 0.945531
Colors: 4
Histogram: <--- matches image
3: ( 0, 0, 0) #000000 gray(0)
2: ( 1, 1, 1) #010101 gray(1)
1: ( 2, 2, 2) #020202 gray(2)
3: ( 3, 3, 3) #030303 gray(3)

Creating a 32 bit image and saving as tif

This is a very basic question but I do not seem to find a good solution to it. I want to create a black (all zeros) 32 bit image with dimension 244 X 244 and save it as tif. I tried some modules like PIL but all I got was a single channel RGB image. Any suggestions? Any links?
Thank you for the help and apologies if the question is too basic!
Hopefully this will help:
#!/usr/local/bin/python3
import numpy as np
from PIL import Image
# Numpy array containing 244x244 solid black image
solidBlackImage=np.zeros([244,244,3],dtype=np.uint8)
img=Image.fromarray(solidBlackImage,mode="RGB")
img.save("result.tif")
The image I get as a result can be examined as follows with ImageMagick, and seen to be a 24-bit image:
identify -verbose result.tif | more
Output
Image: result.tif
Format: TIFF (Tagged Image File Format)
Mime type: image/tiff
Class: DirectClass
Geometry: 244x244+0+0
Units: PixelsPerInch
Colorspace: sRGB
Type: Bilevel
Base type: TrueColor
Endianess: LSB
Depth: 8/1-bit
Channel depth:
Red: 1-bit
Green: 1-bit
Blue: 1-bit
...
...
Or, you can verify with tiffinfo:
tiffinfo result.tif
Output
TIFF Directory at offset 0x8 (8)
Image Width: 244 Image Length: 244
Bits/Sample: 8
Compression Scheme: None
Photometric Interpretation: RGB color
Samples/Pixel: 3
Rows/Strip: 244
Planar Configuration: single image plane
Another option might be pyvips as follows, where I can specify LZW compression as well:
#!/usr/local/bin/python3
import numpy as np
import pyvips
width,height,bands=244,244,3
# Numpy array containing 244x244 solid black image
solidBlackImage=np.zeros([height,width,bands],dtype=np.uint8)
# Convert numpy to vips image and save with LZW compression
vi = pyvips.Image.new_from_memory(solidBlackImage.ravel(), width, height, bands,'uchar')
vi.write_to_file('result.tif',compression='lzw')
That results in this:
tiffinfo result.tif
Output
TIFF Directory at offset 0x3ee (1006)
Image Width: 244 Image Length: 244
Resolution: 10, 10 pixels/cm
Bits/Sample: 8
Sample Format: unsigned integer
Compression Scheme: LZW
Photometric Interpretation: RGB color
Orientation: row 0 top, col 0 lhs
Samples/Pixel: 3
Rows/Strip: 128
Planar Configuration: single image plane
Predictor: horizontal differencing 2 (0x2)

why can't I see the decoded string?

I have a base64 string and I'm trying to figure out what it was, but I can't see anything. What am I doing wrong? Is this
>>> import base64
>>> b = base64.b64decode("FAAAAAMAAAAGAAAACQAAAAwAAAA=")
>>> b
b'\x14\x00\x00\x00\x03\x00\x00\x00\x06\x00\x00\x00\t\x00\x00\x00\x0c\x00\x00\x00'
>>> print(b.decode("utf16"))
>>> print(b.decode("utf8"))
>>>
It it is Base 64 encoding then it is not UTF-16 encoding, nor UTF-8. Have a look at RFC 3548. The Base 64 can be found at page 4 of the document.
Acually, the very purpose is different. The UTF-x encodings are here to encode a unicode string into a binary stream. That is, the abstract string is the decoded form. On the other hand, Base X and the like encodings are here to encode the original binary into a stream of selected ASCII values (basically small integers) so that the binary content could be transfered via e-mail that accepts only characters. The binary is the decoded, original form.
In your case, it looks that as if the serie of integers (32-bit) was transfered: 20, 3, 6, 9, and 12.
Updated later to answer the comment below: How I got the values...
b'\x14\x00\x00\x00\x03\x00\x00\x00\x06\x00\x00\x00\t\x00\x00\x00\x0c\x00\x00\x00'
The b prefix of the literal says it is the literal with the bytes type value. The bytes is a stream of small integers -- each of one byte, that is from zero to 255. When displayed as the literals, the hexadecimal notation of the small integers is used if the related ASCII character cannot be easily displayed -- starting with \x followed by two hexadecimal numerals. The \t is the representation of the tab character which has the ordinal value 9.
However, you can also convert it to the list of integers:
>>> list(b)
[20, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 12, 0, 0, 0]
Now it is more apparent. The zero is the filler if the values are small enough to fit into a single byte. The order of bytes is caused by endianness of the OS/machine. So, actually, it should be hexa (as five 32-bit integers):
00000014 00000003 00000006 00000009 0000000c
Which is:
20 3 6 9 12
In other words, the b'\x14\x00\x00\x00\x03\x00\x00\x00\x06\x00\x00\x00\t\x00\x00\x00\x0c\x00\x00\x00' is actually not a string. It is a bytes literal that captures the value of 5 * 4 bytes. The bytes is a sequence of small integers, not of characters. It is more apparent when you try:
>>> for value in b:
... print(value)
...
20
0
0
0
3
0
0
0
6
0
0
0
9
0
0
0
12
0
0
0
>>> type(b)
<class 'bytes'>
>>> type(b[0])
<class 'int'>
>>>

Resources