You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
These are required for compatibility with ImageView and generally fill out the package.
This also changes the design to always use `RGB{N0f8}` for the colors.
Copy file name to clipboardExpand all lines: README.md
+37-5Lines changed: 37 additions & 5 deletions
Original file line number
Diff line number
Diff line change
@@ -33,7 +33,33 @@ julia> convert(RGB, c)
33
33
RGB{N0f16}(0.75,0.87549,0.09117)
34
34
```
35
35
36
-
The latter is how this color would be rendered in a viewer; embedded in a function, the conversion is extremely well optimized (~2.2ns on the author's machine).
36
+
The latter is how this color would be rendered in a viewer.
37
+
38
+
## Overflow protection
39
+
40
+
Depending on the colors you pick for conversion to RGB (e.g., `channels`), it is possible to exceed the 0-to-1 bounds of RGB.
41
+
With the choice above,
42
+
43
+
```julia
44
+
julia> c =ctemplate(0.99, 0.99)
45
+
(0.99001N0f16₁, 0.99001N0f16₂)
46
+
47
+
julia>convert(RGB, c)
48
+
ERROR: ArgumentError: component type N0f16 is a 16-bit type representing 65536 values from 0.0 to 1.0,
49
+
but the values (0.9900053f0, 1.7664759f0, 0.36105898f0) do not lie within this range.
50
+
See the READMEs for FixedPointNumbers and ColorTypes for more information.
51
+
Stacktrace:
52
+
[...]
53
+
```
54
+
55
+
If you want to guard against such errors, one good choice would be
56
+
57
+
```julia
58
+
julia>convert(RGB{Float32}, c)
59
+
RGB{Float32}(0.9900053, 1.7664759, 0.36105898)
60
+
```
61
+
62
+
Conversions to floating-point types also tend to be faster, since the values do not have to be checked.
37
63
38
64
## Advanced usage
39
65
@@ -43,9 +69,15 @@ However, constructing `ctemplate` as above is an inherently non-inferrable opera
Note the absence of `[]` brackets around the fluorophore names. For such constructors, `N0f8` is the only option if you're
50
-
looking up the RGB values with `fluorophore_rgb`; however, if you hard-code the RGB values there is no restriction
51
-
on the element type.
75
+
Note the absence of `[]` brackets around the fluorophore names.
76
+
77
+
## Why are the RGB colors encoded in the *type*? Why not a value field?
78
+
79
+
In many places, JuliaImages assumes that you can convert from one color space to another purely from knowing the type you want to convert to. This would not be possible if the RGB colors were encoded as a second field of the color.
80
+
81
+
## I wrote some code and got lousy performance. How can I fix it?
82
+
83
+
To achieve good performance, in some cases the RGB *values* must be aggressively constant-propagated, a feature available only on Julia 1.7 and higher. So if you're experiencing this problem on Julia 1.6, try a newer version.
Compat.@constprop:aggressivefunctionColorMixture{T,N,Cs}(channels::NTuple{N}) where {T,N,Cs}
54
-
Cs isa NTuple{N,RGB{T}} ||throw(TypeError(:ColorMixture, "incompatible color types", NTuple{N,RGB{T}}, typeof(Cs)))
54
+
Cs isa NTuple{N,RGB{N0f8}} ||throw(TypeError(:ColorMixture, "", NTuple{N,RGB{N0f8}}, Cs))
55
55
returnnew{T,N,Cs}(channels)
56
56
end
57
57
end
58
58
ColorMixture{T,N,Cs}(channels::Vararg{Real,N}) where {T,N,Cs} =ColorMixture{T,N,Cs}(channels)
59
-
Compat.@constprop:aggressiveColorMixture{T}(Cs::NTuple{N,RGB{T}}, channels::NTuple{N,Real}) where {T,N} =ColorMixture{T,N,Cs}(channels)
60
-
ColorMixture{T}(Cs::NTuple{N,AbstractRGB}, channels::NTuple{N,Real}) where {T,N} =ColorMixture{T,N,RGB{T}.(Cs)}(channels)
61
-
ColorMixture{T}(Cs::NTuple{N,AbstractRGB}, channels::Vararg{Real,N}) where {T,N} =ColorMixture{T}(Cs, channels)
59
+
Compat.@constprop:aggressiveColorMixture{T}(Cs::NTuple{N,RGB{N0f8}}, channels::NTuple{N,Real}) where {T,N} =ColorMixture{T,N,Cs}(channels)
60
+
Compat.@constprop:aggressiveColorMixture{T}(Cs::NTuple{N,AbstractRGB}, channels::NTuple{N,Real}) where {T,N} =ColorMixture{T,N,RGB{N0f8}.(Cs)}(channels)
61
+
Compat.@constprop:aggressiveColorMixture{T}(Cs::NTuple{N,AbstractRGB}, channels::Vararg{Real,N}) where {T,N} =ColorMixture{T}(Cs, channels)
62
62
63
-
@inline_promote_typeof(::Type{C1}, ::Type{C2}) where {C1,C2} =promote_type(C1, C2)
64
-
@inline_promote_typeof(::Type{C1}, ::Type{C2}, obj, objs...) where {C1,C2} =
@testconvert(RGB, c) ≈0.5*channels[1] +0.5*channels[2]
32
33
34
+
fchannels =float.(channels)
35
+
if Base.VERSION>=v"1.8.0-DEV.363"
36
+
@test_throwsr"ColorMixture.*expected Tuple{RGB{N0f8}, +RGB{N0f8}}.*got a value of type Tuple{RGB{Float32}, +RGB{Float32}}"ColorMixture{Float32,2,fchannels}(0.1, 0.2)
0 commit comments