Comments (13)
Crayons.jl has the conversion feature, but I don't think there is a public API just for the conversion. At least, Crayons.jl does not provide an interface to the types defined in ColorTypes.jl.
Another point of concern is that Crayons.jl's implementation is not compatible with XTerm256. (cf. JuliaDocs/ANSIColoredPrinters.jl#8) FWIW, ImageInTerminal.jl has the same issue.
from colors.jl.
At least, as I mentioned above, the current implementations of Crayons.jl and ImageInTerminal.jl assume so-called web-safe colors, not so-called terminal colors.
Therefore, the gist version is better WRT the palette. The problem is how to find the closest color.
On the other hand, converting from a terminal color (index) to RGB is easy.
using Colors, FixedPointNumbers
_to_term_tone256(v::Integer) = v * 0x28 + (v === zero(v) ? 0x00 : 0x37)
function from_term256(i::Integer)
i8 = i % UInt8
if i8 < 0x10
term16 = RGB.(reinterpret.(RGB24, (0x000000, 0x800000, 0x008000, 0x808000,
0x000080, 0x800080, 0x008080, 0xc0c0c0,
0x808080, 0xff0000, 0x00ff00, 0xffff00,
0x0000ff, 0xff00ff, 0x00ffff, 0xffffff)))
return @inbounds term16[i8 + 1]
elseif i8 < 0xe8
c = i8 - 0x10
r = _to_term_tone256(c ÷ 0x24) % UInt8
g = _to_term_tone256((c ÷ 0x6) % 0x6) % UInt8
b = _to_term_tone256(c % 0x6) % UInt8
return RGB(reinterpret.(N0f8, (r, g, b))...)
else
c = i8 - 0xe8
return RGB(reinterpret(N0f8, c * 0xa + 0x8))
end
end
from colors.jl.
Crayons.jl is not dependent on ColorTypes.jl. That's both an advantage and a disadvantage. I am not in a position to decide its dependency.
from colors.jl.
I think this already exists. See https://github.com/KristofferC/Crayons.jl
from colors.jl.
Note that I have considered this issue before, and I realized that finding an approximate color is not so easy.
from colors.jl.
Micah gave me permission to make public the ported code. You can find it in this gist, though it will probably need a lot of clean-up (see original gist for more detail and notes in comments).
I also contacted Kristoffer, who wrote Crayons.jl. This is what he wrote. This is very reminiscent of this comment in the original gist. Perhaps someone that knows more about colours can shed some light on which method might be better.
Let me know what you think @kimikage.
from colors.jl.
I'm not happy with it's performance, but the following just works.
_to_term_tone6(v::UInt8) = (((max(v, 0x4a) + 0x0005) * 0x00cd) >> 0xd) - 0x1
to_term256(@nospecialize(c::Color)) = to_term256(RGB24(c))
function to_term256(c::C) where C <: AbstractRGB
rgb = RGB24(c)
r0 = reinterpret(red(rgb))
g0 = reinterpret(green(rgb))
b0 = reinterpret(blue(rgb))
rt = _to_term_tone6(r0)
gt = _to_term_tone6(g0)
bt = _to_term_tone6(b0)
d = max(r0, g0, b0) - min(r0, g0, b0)
if (rt === gt === bt) || d < 0x15
gr16 = 0x003d * r0 + 0x0079 * g0 + 0x0017 * b0
ths = (0x04, 0x5c, 0x61, 0x84, 0x89, 0xac, 0xb1, 0xd4, 0xd9, 0xf7) .* 0x00cd
if mapreduce(th -> gr16 < th, ⊻, ths; init=false)
return Int(min((gr16 - 0x0334) >> 0xb, 0x17)) + 232
end
end
return Int(rt * 0x24 + gt * 0x6 + bt) + 16
end
from colors.jl.
The left shows the nearest neighbor colors based on DE_2000(1, 1, 1)
, and the right shows the channel-wise rounded colors. The result on the left is not necessarily the best (e.g. there should be no sharp edge corners), but the difference is certainly significant.
There are several possible approaches to improve the conversion, but there are the following problems.
- Searching with a loop is slow.
- Lookup tables tend to be huge.
- Converting to a color space such as Lab/Luv is expensive.
from colors.jl.
Y (Rec.601) - R - B (time-y-x)
Y (Rec.601) - G - B (time-y-x)
In the figures above, you can see something like a checker pattern. In other words, this does not seem to be a problem that can be solved by converting to a perceptually uniform color space (e.g. Lab/Luv). This is because converting to a perceptually uniform color space will result in a discontinuity (i.e. zigzag) in the color index space.
Perhaps it is better to diffuse the rounding error in RGB space.
from colors.jl.
As long as round-trip compatibility is ensured for 240 colors, there is no need to maintain compatibility for the rest. So, I think improvements can be left as a future task.
The other thing we need to decide is the API design.
One option is to provide conversion methods like to_term256
/from_term256
.
Another option is to define a single-component color like Term256Color <: Color{UInt8, 1}
and use the convert
scheme for its conversion. However, currently, Color{T,1}
is interpreted as grayscale, which can cause trouble.
from colors.jl.
I know very little about this. My understanding is that you're going to add this into Colors.jl. Just curious to ask, is there any reason that we can't add/extend this functionality inside Crayons?
The other thing we need to decide is the API design.
Both to_term256
/from_term256
and Term256Color
are good to me.
from colors.jl.
This is off-topic, but is there a package for color quantization or color reduction in the JuliaImages ecosystem?
The feature for mapping pixel colors to a specific palette (with high quality but high cost) should be there.
from colors.jl.
I think I've supported this feature in JuliaImages/ImageInTerminal.jl#62... Maybe I should just port the codes to Colors?
from colors.jl.
Related Issues (20)
- move storage type conversion trait from ImageCore to Colors HOT 6
- Optimizing the types used for intermediate calculations HOT 5
- Source of the YIQ transform matrix HOT 1
- is `inv` on Colors well defined? HOT 4
- Fatal performance degradation due to precompilation or inference bugs HOT 8
- MethodError: no method matching coloralpha(::Type{RGB24}) HOT 1
- What should `default_brettel_neutral` be? HOT 1
- Ambiguity with AbstractTrees
- 'Render' colours in REPL HOT 15
- in the README, put a link on the home page HOT 2
- colorwheel generator HOT 1
- add colorwheel generator HOT 1
- Release v0.13? HOT 2
- Ambiguous show method for `Union{}[]` HOT 3
- colormap("<Color>", maxcount; w=<Int>, logscale=<Bool>) stackoverflows HOT 7
- oklab/oklch for CSS4 and cheap deltaE HOT 1
- BGR interpreted as RGB HOT 1
- Luv and LCHuv gives incorrect color values for low lightness cyan HOT 1
- Support for Preferences.jl HOT 2
- Dark Mode on website makes it nearly-impossible to see names on the namedcolors page HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from colors.jl.