In the course of this discussion on the fastest way to display large matrices as images, I noticed that the get(colorscheme, data) function is not as fast as it could be, and allocates a lot of large temporary arrays (the same size as the image).
The following function seems to be more than 2x faster, and allocates 5x less memory (it only allocates the output image):
import ColorSchemes: AllowedInput, defaultrange
import ColorVectorSpace, Colors
# faster weighted_color_mean that assumes w ∈ [0,1] and
# exploits ColorVectorSpace operations for RGB and Gray types.
fast_weighted_color_mean(w::Real, c1, c2) = Colors.weighted_color_mean(w, c1, c2)
fast_weighted_color_mean(w::Real, c1::ColorVectorSpace.MathTypes, c2::ColorVectorSpace.MathTypes) = w*c1 + (1-w)*c2
function myget(cscheme::ColorScheme, X::AllowedInput, rangescale::NTuple{2,<:Real}=defaultrange(x))
rangemin, rangemax = !iszero(rangescale[2] - rangescale[1]) ?
rangescale : (zero(rangescale[1]), oneunit(rangescale[2]))
scaleby = (length(cscheme) - 1) / (rangemax - rangemin)
return map(X) do x
xclamp = clamp(x, rangemin, rangemax)
before_fp = (xclamp - rangemin) * scaleby + 1
before = round(Int, before_fp, RoundDown)
after = min(before + 1, length(cscheme))
cpt = before_fp - before
# blend between the two colors adjacent to the point
@inbounds fast_weighted_color_mean(cpt, cscheme.colors[before], cscheme.colors[after])
end
end
It adds a dependency on ColorVectorSpace.jl, but that's pretty lightweight (and is pulled in by things like Images.jl anyway).
In the course of this discussion on the fastest way to display large matrices as images, I noticed that the
get(colorscheme, data)
function is not as fast as it could be, and allocates a lot of large temporary arrays (the same size as the image).The following function seems to be more than 2x faster, and allocates 5x less memory (it only allocates the output image):
It adds a dependency on ColorVectorSpace.jl, but that's pretty lightweight (and is pulled in by things like Images.jl anyway).