Jump to content
  • Sky
  • Blueberry
  • Slate
  • Blackcurrant
  • Watermelon
  • Strawberry
  • Orange
  • Banana
  • Apple
  • Emerald
  • Chocolate
  • Charcoal
  • 0
swg2you

What algorithm is used to approximate colors?

Question

Hello.

When output to the monitor, the color 0xRRGGBB is approximated to the palette set in the monitor.  I need to know exactly which color I will get through gpu.get when outputting color 0xRRGGBB.

Can you answer (or show example on the Lua): What algorithm is used to approximate colors?

Sorry for the bad english.

-=-

Below, just a small program that I use to test colors. Maybe it will be useful to someone.

sicot.lua   "SimpleColorTester",  "MC 1.12.2", "OpenComputers  version 1.7.0.4", "Lua 5.3"

local gpu=require('component').gpu
local ev=require('event')

local function setColor(f,b)
  gpu.setForeground(f)
  gpu.setBackground(b)
end

local w=0xFFFFFF
require('term').clear()
gpu.fill(1,1,80,12," ")
gpu.set(27,1,'← click →')
gpu.set(69,1,' RMB to exit')
gpu.set(69,3,'◄ Tier 2')
gpu.set(69,5,'◄ Tier 3')
gpu.set(69,6,'       ▼')

local function showcolor(c)
  for i=0,24 do
    local b= (c & 2^i) >> i 
    setColor((1-b)*w, b*w)   
    gpu.set(24-i,1,tostring(b))
  end
  setColor(c ~ w, c)  
  gpu.fill(1,3,24,3," ")
  gpu.set(7,4,string.format('Set: %06X',c))
  local _,_,bg=gpu.get(1,3)
  gpu.set(7,5,string.format('Get: %06X',bg))
  setColor(w,0)
  gpu.set(1,2,'└──┴┴──┘└──┴┴──┘└──┴┴──┘')
end

local color=math.random(w)
showcolor(color)

local s='SimpleColorTest'
for i=1,#s do
  setColor(color ~ w, color) 
  gpu.set(36+i*2,1,string.sub(s,i,i)..' ')
  color=math.random(w)
end

--[[ https://en.wikipedia.org/wiki/List_of_software_palettes#6-8-5_levels_RGB
    Tier3 palette is constructed with six levels for red, eight levels for green and five levels for the blue primaries, 
	giving 6×8×5 = 240 combinations. The index can be addressed by (40×R)+(5×G)+B, with R ranging from 0 to 5, G from 
	0 to 7 and B from 0 to 4. Levels are chosen in function of sensibility of the normal human eye to every primary color.]]


--Tier2: safe colors, use this if you need that your program look the same on tier2 and tier3 monitors
palTier2={0x000000,0x333333,0x333399,0x336600,0x336699,0x33CC33,0x663300,0x6699FF,0x9933CC,0xCC66CC,0xCCCCCC,0xFF3333,0xFF6699,0xFFCC33,0xFFFF33,0xFFFFFF}
--alternative palettes
palCGA={0x000000,0x0000AA,0x00AA00,0x00AAAA,0xAA0000,0xAA00AA,0xAA5500,0xAAAAAA,0x555555,0x5555FF,0x55FF55,0x55FFFF,0xFF5555,0xFF55FF,0xFFFF55,0xFFFFFF}
palRGBI={0x000000,0x0000AA,0x00AA00,0x00AAAA,0xAA0000,0xAA00AA,0xAAAA00,0xAAAAAA,0x555555,0x5555FF,0x55FF55,0x55FFFF,0xFF5555,0xFF55FF,0xFFFF55,0xFFFFFF}
palZX={0x000000,0x0000CD,0xCD0000,0xCD00CD,0x00CD00,0x00CDCD,0xCDCD00,0xCDCDCD,0x000000,0x0000FF,0xFF0000,0xFF00FF,0x00FF00,0x00FFFF,0xFFFF00,0xFFFFFF}
pal7f={0x000000,0x000080,0x008000,0x008080,0x800000,0x800080,0x808000,0x808080,0x1f1f1f,0x1f1fFF,0x1fFF1f,0x1fFFFF,0xFF1f1f,0xFF1fFF,0xFFFF1f,0xFFFFFF}

--show getPaletteColor(0..15)
for x=0,7 do
  for y=0,1 do
    local c=gpu.getPaletteColor(x+y*8)
    setColor(w,c)
    gpu.set(1+x*10, 14+y, '   ')
    setColor(w,0)
    gpu.set(1+x*10+3, 14+y, string.format('%06X',c))
  end
end

--show Tier2 safe colors
for x=0,15 do
  setColor(w,palTier2[x+1]) 
  gpu.set(36+2*x, 3, '  ') 
end

--show Tier3, by default 16 shades of gray
for y=0,0xF do 
  setColor(w,(y+1)*0x0f0f0f) 
  gpu.set(36+y*2, 5, '  ')
end

--Tier3: big palette 6r*8g*5b=240 fixed colors (approximately) are generated by the following algorithm
for r=0,5 do
  for g=0,7 do
    for b=0,4 do
      setColor(w, r*0x330000 + g*0x2400 + b*0x3F)
      gpu.set(1+2*(b+g*5), 7+r, '  ')
    end 
  end
end
-- for greater accuracy it is necessary to use tables
--  RR = {0x00, 0x33, 0x66, 0x99, 0xCC, 0xFF}
--  GG = {0x00, 0x24, 0x49, 0x6D, 0x92, 0xB6, 0xDB, 0xFF}
--  BB = {0x00, 0x40, 0x80, 0xC0, 0xFF}
-- and formula color = RR[r] << 16  +  GG[g] << 8  +  BB[b]
-- when r = 1 .. 6;    g = 1 .. 8;    b = 1 .. 5

local t=ev.timer(1,function() setColor(w,0) gpu.set(69,1,'→RMB to exit') os.sleep(.05) gpu.set(69,1,' RMB to exit') end, math.huge)
repeat
  local _,_,x,y,k=ev.pull('touch')
  local s,fg,bg=gpu.get(x,y)
  if y==1 and x<=24 then
    local bit=24-x
    color = color ~ 2^bit 
    showcolor(color)
  else
    color=bg
    showcolor(color)
  end
  --temp test compute approximation
  r = (color & 0xFF0000) >> 16
  g = (color & 0x00FF00) >> 8
  b = color & 0x0000FF
  r = r*6//256
  g = g*8//256
  b = b*5//256
  RR={0x00,0x33,0x66,0x99,0xCC,0xFF}
  GG={0x00,0x24,0x49,0x6D,0x92,0xB6,0xDB,0xFF}
  BB={0x00,0x40,0x80,0xC0,0xFF}
  --temp show test
  gpu.set(1+00, 16, string.format('%02X',RR[r+1]))
  gpu.set(1+10, 16, string.format('%02X',GG[g+1]))
  gpu.set(1+20, 16, string.format('%02X',BB[b+1]))
  
until k==1
ev.cancel(t)
setColor(w,0)
require('term').clear()

 

Link to post
Share on other sites

2 answers to this question

Recommended Posts

  • 0
2 hours ago, Fingercomp said:

This page, though in Russian, may be useful to you. The code there contains functions to deflate a color into its palette index and vice versa. Generate a color palette and use palette:inflate(palette:deflate(color)).

Thanks a lot.

I correctly understood? "хитромудрый код" is taken directly from the code of OpenComputers?

P.S Say hello to computercraft.ru ;)

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use and Privacy Policy.