Skip to content

Commit

Permalink
Generalize conversions within the same base color (#264)
Browse files Browse the repository at this point in the history
This supports adding/stripping alpha for colors other than `Color3`.
  • Loading branch information
kimikage authored Aug 16, 2021
1 parent 38bb9dc commit 8574435
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 4 deletions.
13 changes: 9 additions & 4 deletions src/conversions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -78,17 +78,22 @@ convert(::Type{C}, c::Color, alpha) where {C<:TransparentColor} = cconvert(ccolo
cconvert(::Type{C}, c::Color, alpha) where {C<:TransparentColor} =_convert(C, base_color_type(C), base_color_type(c), c, alpha)

# Fallback definitions that print nice error messages
_convert(::Type{C}, ::Any, ::Any, c) where {C} = error("No conversion of ", c, " to ", C, " has been defined")
_convert(::Type{C}, C1::Any, C2::Any, c, alpha) where {C} = error("No conversion of (", c, ",alpha=$alpha) to ", C, " with consistency-types $C1 and $C2 has been defined")
_convert(C::Type, ::Any, ::Any, c) = error("No conversion of ", c, " to ", C, " has been defined")
_convert(C::Type, C1::Any, C2::Any, c, alpha) = error("No conversion of (", c, ",alpha=$alpha) to ", C, " with consistency-types $C1 and $C2 has been defined")

# Any AbstractRGB types can be interconverted
_convert(::Type{Cout}, ::Type{C1}, ::Type{C2}, c) where {Cout<:AbstractRGB,C1<:AbstractRGB,C2<:AbstractRGB} = Cout(red(c), green(c), blue(c))
_convert(::Type{A}, ::Type{C1}, ::Type{C2}, c, alpha=alpha(c)) where {A<:TransparentRGB,C1<:AbstractRGB,C2<:AbstractRGB} = A(red(c), green(c), blue(c), alpha)

# Implementations for when the base color type is not changing
# These might strip/add transparency, however
_convert(::Type{Cout}, ::Type{Ccmp}, ::Type{Ccmp}, c) where {Cout<:Color3,Ccmp<:Color3} = Cout(comp1(c), comp2(c), comp3(c))
_convert(::Type{A}, ::Type{Ccmp}, ::Type{Ccmp}, c, alpha=alpha(c)) where {A<:Transparent3,Ccmp<:Color3} = A(comp1(c), comp2(c), comp3(c), alpha)
function _convert(::Type{Cout}, ::Type{C1}, ::Type{C1}, c) where {Cout<:Color, C1<:Color}
Cout(comps(color(c))...)
end
function _convert(::Type{Cout}, ::Type{C1}, ::Type{C1}, c,
alpha=alpha(c)) where {Cout<:TransparentColor, C1<:Color}
Cout(comps(color(c))..., alpha)
end

# Grayscale
_convert(::Type{Cout}, ::Type{C1}, ::Type{C2}, c) where {Cout<:AbstractGray,C1<:AbstractGray,C2<:AbstractGray} = Cout(gray(c))
Expand Down
21 changes: 21 additions & 0 deletions test/conversions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ using ColorTypes.FixedPointNumbers
using Test
using ColorTypes: ColorTypeResolutionError

@isdefined(CustomTypes) || include("customtypes.jl")
using .CustomTypes

@testset "rgb promotions" begin
@test promote( RGB{N0f8}(0.2,0.3,0.4), RGB(0.3,0.8,0.1)) === ( RGB{Float64}(0.2N0f8,0.3N0f8,0.4N0f8), RGB{Float64}(0.3,0.8,0.1))
@test promote( RGB{N0f8}(0.2,0.3,0.4), RGBA(0.3,0.8,0.1)) === (RGBA{Float64}(0.2N0f8,0.3N0f8,0.4N0f8), RGBA{Float64}(0.3,0.8,0.1))
Expand Down Expand Up @@ -664,6 +667,24 @@ end
end
end

@testset "conversions in the same color space" begin
@test convert(Cyanotype{Float32}, Cyanotype{Float64}(0.8)) === Cyanotype{Float32}(0.8)

@test convert(C2, C2{Float64}(0.4,0.6)) === C2{Float64}(0.4,0.6)
@test convert(C2{Float32}, C2{Float64}(0.4,0.6)) === C2{Float32}(0.4,0.6)
@test convert(C2, C2A{Float64}(0.4,0.6,0.5)) === C2{Float64}(0.4,0.6)
@test convert(C2A, C2A{Float32}(0.4,0.6,0.5)) === C2A{Float32}(0.4,0.6,0.5)
@test convert(C2A, C2{Float64}(0.4,0.6)) === C2A{Float64}(0.4,0.6,1.0)
@test convert(C2A, C2{Float32}(0.4,0.6), 0.25) === C2A{Float32}(0.4,0.6,0.25)

@test convert(CMYK, CMYK{Float64}(0.2,0.4,0.6,0.8)) === CMYK{Float64}(0.2,0.4,0.6,0.8)
@test convert(CMYK{Float32}, CMYK{Float64}(0.2,0.4,0.6,0.8)) === CMYK{Float32}(0.2,0.4,0.6,0.8)
@test convert(CMYK, ACMYK{Float64}(0.2,0.4,0.6,0.8,0.5)) === CMYK{Float64}(0.2,0.4,0.6,0.8)
@test convert(ACMYK, ACMYK{Float32}(0.2,0.4,0.6,0.8,0.5)) === ACMYK{Float32}(0.2,0.4,0.6,0.8,0.5)
@test convert(ACMYK, CMYK{Float64}(0.2,0.4,0.6,0.8)) === ACMYK{Float64}(0.2,0.4,0.6,0.8,1.0)
@test convert(ACMYK, CMYK{Float32}(0.2,0.4,0.6,0.8), 0.25) === ACMYK{Float32}(0.2,0.4,0.6,0.8,0.25)
end

@testset "conversions from gray to rgb" begin
Crgb = filter(T -> T <: AbstractRGB, ColorTypes.parametric3)
Ctransparent = unique(vcat(coloralpha.(Crgb), alphacolor.(Crgb)))
Expand Down

0 comments on commit 8574435

Please sign in to comment.