# New user of Images.jl ... trouble saving grayscale PNG

**URL:** <https://discourse.julialang.org/t/new-user-of-images-jl-trouble-saving-grayscale-png/103553>\
**Category:** New to Julia\
**Tags:** juliaimages\
**Created:** [September 5, 2023, 8:42pm UTC](https://discourse.julialang.org/t/new-user-of-images-jl-trouble-saving-grayscale-png/103553 "2023-09-05T20:42:35Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![frylock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/frylock/32/50213_2.png) [@frylock](https://discourse.julialang.org/u/frylock)\
**Post date:** [September 5, 2023, 8:42pm UTC](https://discourse.julialang.org/t/new-user-of-images-jl-trouble-saving-grayscale-png/103553/1 "2023-09-05T20:42:35Z")

</div>

I am getting a copy of the red channel of an image from the graphics card as a Float32. What I get back has a range of 0 to 1.865 (granted, I may have done something wrong, I would have figured it was supposed to be from 0 to 1), anyhow, to quiet down the errors, I divided by the maximum value to get the buffer back in the range from 0 to 1.

I then try to set the buffer up for saving to a file:

```julia
using Images

# ... elided ...

samples = reshape(samples, WIDTH, HEIGHT)
samples = transpose(colorview(Gray, n0f16.(samples)))
save("framebuffer.png", samples)

```

This generated a lot of error text, and I am not sure if I am using “save” correctly?

> **error text**
>
> ```julia
> 
> (typeof(pixel_samples), minimum(pixel_samples), maximum(pixel_samples)) = (Matrix{Gray{N0f8}}, Gray{N0f8}(0.0), Gray{N0f8}(1.0))
> ┌ Warning: Mapping to the storage type failed; perhaps your data had out-of-range values?
> │ Try `map(clamp01nan, img)` to clamp values to a valid range.
> └ @ ImageMagick ~/.julia/packages/ImageMagick/KDZC2/src/ImageMagick.jl:179
> Errors encountered while save FileIO.File{FileIO.DataFormat{:PNG}, String}("framebuffer.png").
> All errors:
> ===========================================
> MethodError: no method matching save(::FileIO.File{FileIO.DataFormat{:PNG}, String}, ::Tuple{DataType, Gray{N0f8}, Gray{N0f8}})
> 
> Closest candidates are:
> save(::FileIO.File{FileIO.DataFormat{:PNG}}, ::S; kwargs...) where {T, S<:Union{AbstractArray{T, 3}, AbstractMatrix}}
> @ ImageIO ~/.julia/packages/ImageIO/XthUV/src/ImageIO.jl:69
> save(::FileIO.File{FileIO.DataFormat{:QOI}}, ::Any...; kwargs...)
> @ ImageIO ~/.julia/packages/ImageIO/XthUV/src/ImageIO.jl:152
> save(::FileIO.File{FileIO.DataFormat{:EXR}}, ::Any...; kwargs...)
> @ ImageIO ~/.julia/packages/ImageIO/XthUV/src/ImageIO.jl:141
> 
> ===========================================
> MethodError: no method matching mapIM(::Type{Matrix{Gray{N0f8}}})
> 
> Closest candidates are:
> mapIM(::Bool)
> @ ImageMagick ~/.julia/packages/ImageMagick/KDZC2/src/ImageMagick.jl:319
> mapIM(::UInt32)
> @ ImageMagick ~/.julia/packages/ImageMagick/KDZC2/src/ImageMagick.jl:318
> mapIM(::UInt8)
> @ ImageMagick ~/.julia/packages/ImageMagick/KDZC2/src/ImageMagick.jl:316
> 
> ===========================================
> ArgumentError: Argument does not support conversion to png.
> ===========================================
> 
> Fatal error:
> ERROR: LoadError: MethodError: no method matching save(::FileIO.File{FileIO.DataFormat{:PNG}, String}, ::Tuple{DataType, Gray{N0f8}, Gray{N0f8}})
> 
> Closest candidates are:
> save(::FileIO.File{FileIO.DataFormat{:PNG}}, ::S; kwargs...) where {T, S<:Union{AbstractArray{T, 3}, AbstractMatrix}}
> @ ImageIO ~/.julia/packages/ImageIO/XthUV/src/ImageIO.jl:69
> save(::FileIO.File{FileIO.DataFormat{:QOI}}, ::Any...; kwargs...)
> @ ImageIO ~/.julia/packages/ImageIO/XthUV/src/ImageIO.jl:152
> save(::FileIO.File{FileIO.DataFormat{:EXR}}, ::Any...; kwargs...)
> @ ImageIO ~/.julia/packages/ImageIO/XthUV/src/ImageIO.jl:141
> 
> Stacktrace:
> [1] #invokelatest#2
> @ FileIO ./essentials.jl:892 [inlined]
> [2] invokelatest
> @ FileIO ./essentials.jl:889 [inlined]
> [3] action(call::Symbol, libraries::Vector{Union{Base.PkgId, Module}}, file::FileIO.Formatted, args::Tuple{DataType, Gray{N0f8}, Gray{N0f8}}; options::@Kwargs{})
> @ FileIO ~/.julia/packages/FileIO/BE7iZ/src/loadsave.jl:219
> [4] action
> @ FileIO ~/.julia/packages/FileIO/BE7iZ/src/loadsave.jl:196 [inlined]
> [5] action
> @ FileIO ~/.julia/packages/FileIO/BE7iZ/src/loadsave.jl:185 [inlined]
> [6] save(file::String, args::Tuple{DataType, Gray{N0f8}, Gray{N0f8}}; options::@Kwargs{})
> @ FileIO ~/.julia/packages/FileIO/BE7iZ/src/loadsave.jl:129
> [7] save(file::String, args::Tuple{DataType, Gray{N0f8}, Gray{N0f8}})
> @ FileIO ~/.julia/packages/FileIO/BE7iZ/src/loadsave.jl:125
> [8] main()
> @ Main ~/Delete/simple.jl:50
> [9] top-level scope
> @ ~/Delete/simple.jl:54
> Stacktrace:
> [1] handle_error(e::MethodError, q::Base.PkgId, bt::Vector{Union{Ptr{Nothing}, Base.InterpreterIP}})
> @ FileIO ~/.julia/packages/FileIO/BE7iZ/src/error_handling.jl:61
> [2] handle_exceptions(exceptions::Vector{Tuple{Any, Union{Base.PkgId, Module}, Vector}}, action::String)
> @ FileIO ~/.julia/packages/FileIO/BE7iZ/src/error_handling.jl:56
> [3] action(call::Symbol, libraries::Vector{Union{Base.PkgId, Module}}, file::FileIO.Formatted, args::Tuple{DataType, Gray{N0f8}, Gray{N0f8}}; options::@Kwargs{})
> @ FileIO ~/.julia/packages/FileIO/BE7iZ/src/loadsave.jl:228
> [4] action
> @ FileIO ~/.julia/packages/FileIO/BE7iZ/src/loadsave.jl:196 [inlined]
> [5] action
> @ FileIO ~/.julia/packages/FileIO/BE7iZ/src/loadsave.jl:185 [inlined]
> [6] save(file::String, args::Tuple{DataType, Gray{N0f8}, Gray{N0f8}}; options::@Kwargs{})
> @ FileIO ~/.julia/packages/FileIO/BE7iZ/src/loadsave.jl:129
> [7] save(file::String, args::Tuple{DataType, Gray{N0f8}, Gray{N0f8}})
> @ FileIO ~/.julia/packages/FileIO/BE7iZ/src/loadsave.jl:125
> [8] main()
> @ Main ~/Delete/simple.jl:50
> [9] top-level scope
> @ ~/Delete/simple.jl:54
> [10] include(fname::String)
> @ Base.MainInclude ./client.jl:489
> [11] top-level scope
> @ REPL[1]:1
> [12] top-level scope
> @ ~/opt/julia/usr/share/julia/stdlib/v1.11/REPL/src/REPL.jl:1426
> 
> ```

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [September 6, 2023, 12:58pm UTC](https://discourse.julialang.org/t/new-user-of-images-jl-trouble-saving-grayscale-png/103553/2 "2023-09-06T12:58:24Z")

</div>

[Linking related thread](https://discourse.julialang.org/t/colorizing-a-uint8-matrix/99158/7)

---

<div class="post-metadata">

**Author:** ![frylock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/frylock/32/50213_2.png) [@frylock](https://discourse.julialang.org/u/frylock)\
**Post date:** [September 6, 2023, 1:24pm UTC](https://discourse.julialang.org/t/new-user-of-images-jl-trouble-saving-grayscale-png/103553/3 "2023-09-06T13:24:57Z")

</div>

I tried again with FileIO added to the manifest, and `using FileIO` at the top … same error …

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [September 6, 2023, 1:26pm UTC](https://discourse.julialang.org/t/new-user-of-images-jl-trouble-saving-grayscale-png/103553/4 "2023-09-06T13:26:02Z")

</div>

Did you also use ` ImageIO` ?

---

<div class="post-metadata">

**Author:** ![frylock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/frylock/32/50213_2.png) [@frylock](https://discourse.julialang.org/u/frylock)\
**Post date:** [September 6, 2023, 1:28pm UTC](https://discourse.julialang.org/t/new-user-of-images-jl-trouble-saving-grayscale-png/103553/5 "2023-09-06T13:28:06Z")

</div>

Right now, the include line is `using Images, ImageIO, FileIO`. Same error …

EDIT, ok, not same error … I removed some debug print text just to make sure, and it looks like the _type_ of the result returned from my image-returning function switched from Matrix to tuple of Matrix and two numbers). I’ll go back in git history and figure out exactly what … but the only material changes that I made beyond that were including FileIO and ImageIO in the manifest. **ImageIO seems to be the missing package that when added fixed it.**

In short, thanks, you figured out my problem!
