Fix writing of `Ufixed12` images
julia> img = Image([Gray(Ufixed12(2)) Gray(Ufixed12(0.8))], spatialorder = ["x","y"])
Gray Images.Image with:
data: 1x2 Array{Images.ColorTypes.Gray{FixedPointNumbers.UfixedBase{UInt16,12}},2}
properties:
spatialorder: x y
julia> imwrite(img, "/tmp/test.png")
julia> imgr = imread("/tmp/test.png")
Gray Images.Image with:
data: 1x2 Array{Images.ColorTypes.Gray{FixedPointNumbers.UfixedBase{UInt16,16}},2}
properties:
IMcs: Gray
spatialorder: x y
pixelspacing: 1 1
julia> imgr[1]
Gray{Ufixed16}(0.12497)
julia> imgr[2]
Gray{Ufixed16}(0.04999)
mhm, I'll leave this open as this still seems to persist.
julia> using Images
julia> A = [Gray(N4f12(2)) Gray(N4f12(0.8))]
1×2 Array{Gray{N4f12},2}:
Gray{N4f12}(2.0) Gray{N4f12}(0.8)
julia> save("/tmp/a.png", A)
julia> B = load("/tmp/a.png")
1×2 Array{Gray{N0f16},2}:
Gray{N0f16}(0.12497) Gray{N0f16}(0.04999)
@kimikage If you're available, could you take a look at this issue?
Ufixed12 sounds nostalgic.:smile:
I think this is a issue with documentation. As a matter of fact, the "expected behavior" of ImageMagick.jl is unclear.
If there are the tests for this issue, I will fix something to pass them.
We'd need a mechanism to specify the expected return type. NRRD and TIFF formats provide a mechanism to do this, but I don't think PNG or JPG do. NRRD already supports this, see https://github.com/JuliaIO/NRRD.jl/blob/569413d9fadbee958b65d3452c8e3012e0c240c7/test/runtests.jl#L91-L93
I think PNG files can contain the "sBIT" chunk. However, I don't know whether ImageMagick supports it. Furthermore, I'm not sure how to handle values greater than one.
I don't think this is an elegant method, but it might be useful to have a function for mapi which rotate the bits instead of clamping.
Edit:
Practically speaking, what is wrong other than the documentation?
Should the format be automatically converted to N0f16 when the storage format is 16-bit depth? Is that really a desirable behavior for many users?
Is it a problem that ImageMagick saves the bit depth on its own?
BTW, the Normed-->Normed conversions are different from bit shifting.
The conversion from Nxf1 to Nxf2 is the extreme case. The bit shifting means 2 * x.i, but the actual Normed-> Normed conversion means 3 * x.i. Of course, this is a negligible error in practical fs (e.g. (2^16-1) / (2^12-1) ≈ 16.003663).
PNG's "sBIT" is the very thing to prevent the accumulation of errors due to such a conversion. (Unfortunately, it's ruined by the existence of many non-compliant tools.:stuck_out_tongue_closed_eyes:)
IMO, the conversion method should be specified by the users. It may be a good idea to add utility functions for the conversion.
It does work properly if you use a format like NRRD.
julia> using Images, NRRD
julia> img = [Gray(N4f12(2)) Gray(N4f12(0.8))]
1×2 Array{Gray{N4f12},2} with eltype Gray{N4f12}:
Gray{N4f12}(2.0) Gray{N4f12}(0.8)
julia> save("/tmp/12bit.nrrd", img)
4
julia> imgl = load("/tmp/12bit.nrrd")
1×2 reshape(reinterpret(Gray{N4f12}, ::Matrix{UInt16}), 1, 2) with eltype Gray{N4f12}:
Gray{N4f12}(2.0) Gray{N4f12}(0.8)
Since 12-bit cameras are probably mostly used for scientific imaging, it's acceptable that one should have to use a suitable file format.