I recently asked how to convert Float32
or Uint8
arrays into images in the Images
package. I got an answer for the Float32
case, but am still having trouble figuring out how to save a Uint8
array.
As an example, let's create a random Uint8
array using the traditional Matlab scheme where the dimensions are (m,n,3)
:
array = rand(Uint8, 50, 50, 3);
img = convert(Image, array);
Using the same approach as works for the Float32
case,
imwrite(img, "out.png")
fails with message
ERROR: method 'mapinfo' has no method matching mapinfo(::Type{ImageMagick}, ::Image{Uint8, 3, Image{Uint8, 3, Array{Uint8, 3}}}).
I checked the documentation, and it says
If data encodes color information along one of the dimensions of the array (as opposed to using a ColorValue array, from the Color.jl package), be sure to specify the "colordim" and "colorspace" in properties.
However, inspecting the img
object previously created shows that it has colordim = 3
and colorspace = RGB
already set up, so this can't be the problem.
I then searched the documentation for all instances of MapInfo
. In core.md there is one occurrence:
scalei: a property that controls default contrast scaling upon display. This should be a MapInfo value, to be used for setting the contrast upon display. In the absence of this property, the range 0 to 1 will be used.
But there was no information on what exactly a MapInfo
object is, so I looked further, and in function_reference.md it says:
Here is how to directly construct the major concrete MapInfo types:
MapNone(T), indicating that the only form of scaling is conversion to type T. This is not very safe, as values "wrap around": for example, converting 258 to a Uint8 results in 0x02, which would look dimmer than 255 = 0xff.
...
and some other examples. So I tried to specify scalei = MapNone(Uint8)
as follows:
img2 = Image(img, colordim = 3, colorspace = "RGB", scalei = MapNone(Uint8));
imwrite(img, "out.png")
but got the same error again.
How do you encode Uint8
image data using Images
in Julia?
You can convert back and forth between arrays of primitive types such as UInt8
and arrays of color types. These conversions are achieved in a unified way via two functions: colorview
and channelview
.
Convert array of UInt8
to array of RGB
:
arr = rand(UInt8, 3, 50, 50)
img = colorview(RGB, arr / 255)
Convert back to channel view:
channelview(img)
In this example the RGB color type requires that the entries of the array live in [0,1]
as floating point. I manually converted UInt8
to Float64
using an explicit division by 255
. There is probably a more generic way of achieving this result with reinterpret
or some other function in Images.jl
The colorview
and channelview
functions assume that the channel dimension is the first dimension of the array. You can use permutedims
in case your channels live in a different dimension, or use some function in Images.jl (maybe reinterpretc
?) to do it efficiently without memory copies.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With