Images and the new color representation

I can see that there are quite a few changes concerning Images.

I have a two dimensional array with triples of UInt8 as entries. How do I make it work with ImageView.imshow?
As far as I understand, I must convert the UInt8 to the new type N0f8, but this does not seem to work.

julia> n0f8(UInt8(222))
ERROR: ArgumentError: FixedPointNumbers.Normed{UInt8,8} is an 8-bit type representing 256 values from 0.0 to 1.0; cannot represent 222

If you want to just interpret a UInt8 (with a value from 0 to 255) as a N0f8 (with a value from 0 to 1), then Julia’s built-in reinterpret will do what you want:

julia> reinterpret(N0f8, UInt8(222))
0.871N0f8

julia> reinterpret(N0f8, [UInt8(222), UInt8(0), UInt8(255)])
3-element Array{FixedPointNumbers.Normed{UInt8,8},1}:
 0.871N0f8
 0.0N0f8  
 1.0N0f8  

Perfect!

Why does it fail on tuples? The error message is cryptic.

julia> reinterpret(N0f8, (0xde, 0x00, 0x0c))
ERROR: bitcast: target type not a leaf primitive type
Stacktrace:
 [1] reinterpret(::Type{FixedPointNumbers.Normed{UInt8,8}}, ::Tuple{UInt8,UInt8,UInt8}) at ./essentials.jl:155

because reinterpret does not have a method for tuples, only scalars and arrays. However, Julia’s dot broadcasting can automatically apply it to any collection

julia> reinterpret.(N0f8, (0xde, 0x00, 0x0c))
(0.871N0f8, 0.0N0f8, 0.047N0f8)
2 Likes
julia> A = [(0xff, 0x11, 0x33) (0x22, 0xff, 0xaa); (0x00, 0xff, 0x00) (0x00, 0x00, 0xff)]
2×2 Array{Tuple{UInt8,UInt8,UInt8},2}:
 (0xff, 0x11, 0x33)  (0x22, 0xff, 0xaa)
 (0x00, 0xff, 0x00)  (0x00, 0x00, 0xff)

julia> B = reinterpret(UInt8, A, (3,2,2))
3×2×2 Array{UInt8,3}:
[:, :, 1] =
 0xff  0x00
 0x11  0xff
 0x33  0x00

[:, :, 2] =
 0x22  0x00
 0xff  0x00
 0xaa  0xff

julia> C = normedview(N0f8, B)
3×2×2 Array{N0f8,3}:
[:, :, 1] =
 1.0N0f8    0.0N0f8
 0.067N0f8  1.0N0f8
 0.2N0f8    0.0N0f8

[:, :, 2] =
 0.133N0f8  0.0N0f8
 1.0N0f8    0.0N0f8
 0.667N0f8  1.0N0f8

julia> D = colorview(RGB, C)
2×2 Array{RGB{N0f8},2}:
 RGB{N0f8}(1.0,0.067,0.2)  RGB{N0f8}(0.133,1.0,0.667)
 RGB{N0f8}(0.0,1.0,0.0)    RGB{N0f8}(0.0,0.0,1.0)

Thanks for all the answers. This was as simple as

reinterpret(RGB{N0f8}, A)

where A is the array of UInt8 triples.

Assuming you’re using Images (or at least ImageCore), a more generic solution is colorview(RGB, normedview(A)). You can only call reinterpret on Arrays (though anything with dense storage would be implementable), whereas colorview works for any AbstractArray. colorview will call reinterpret when it’s applicable, and create a special wrapper type when not.

More detail at Home · JuliaImages.

1 Like