Posts: 106
Threads: 6
Joined: Jun 2019
Reputation:
20
Gimp version:
Operating system(s): Linux
For gimp 2.10, is my understanding correct?
Given a region's bytes from a layer ‘l’:
r = l.get_pixel_rgn(0, 0, w, h)
rb = r[:, :]
I think rb will hold the bytes of the channel's values in the machine's native endianess because:
- a region maps onto tiles,
- getting the tile's pixels uses a simple memcpy(), and
- a tile's pixels are in the native endianess.
I'm aware tile data in an XCF file is big-endian from
https://testing.developer.gimp.org/core/...ganization
But I'm interested in what's in memory and guaranteed to be seen through slicing a Python region into a string of bytes.
Posts: 6,790
Threads: 293
Joined: Oct 2016
Reputation:
592
Gimp version:
Operating system(s): Linux
In my code it appears that I assume it's R,G,B. Worrying about endianness would imply that you expect values in data types bigger than bytes?
Posts: 106
Threads: 6
Joined: Jun 2019
Reputation:
20
Gimp version:
Operating system(s): Linux
Hi Ofnuts, Yes, that's right. The image's precision can be integers or floats of 16 or 32 bits.
Posts: 6,790
Threads: 293
Joined: Oct 2016
Reputation:
592
Gimp version:
Operating system(s): Linux
Yesterday, 07:23 PM
(This post was last modified: Yesterday, 07:47 PM by Ofnuts.)
(Yesterday, 05:52 PM)teapot Wrote: Hi Ofnuts, Yes, that's right. The image's precision can be integers or floats of 16 or 32 bits.
OK, so
- I create a 32-bit image, and fill with a (100%,50%,25%) color (values in the FG color selector, in other words #FF8040).
- Get a pixel region. rgn.bpp is 3, so data is converted to one byte per channel.
- Call pdb.gimp_plugin_enable_precision()
- rgn.bpp is now 12 (coherent with 32-bit per channel (no alpha channel).
Then
Code:
➤> rgn=image.active_layer.get_pixel_rgn(0,0,10,10)
➤> rgn.bpp # Check the precision of the returned data
3
➤> # Tell Gimp we are a big boy and can be told the truth
➤> pdb.gimp_plugin_enable_precision()
➤> rgn=image.active_layer.get_pixel_rgn(0,0,10,10)
➤> rgn.bpp
12
➤> # OK, much better (no alpha, so 3 channels of 4 bytes each)
➤> # Let's try some decoding
➤> import struct
➤> struct.unpack('f',rgn[0,0][0:4]) # Native order, get 1 for Red, as expected
(1.0,)
➤> struct.unpack('<f',rgn[0,0][0:4]) # Little-endian order (same as native on my x86 PC, still OK)
(1.0,)
➤> struct.unpack('>f',rgn[0,0][0:4]) # Big-endian, WTF
(4.600602988224807e-41,)
➤> struct.unpack('f',rgn[0,0][4:8]) # Green (obviously linear)
(0.21586056053638458,)
➤> struct.unpack('f',rgn[0,0][8:12]) # Blue (obviously linear too)
(0.051269471645355225,)
➤>
|