Modul:Kontrast boja: razlika između inačica

Izvor: Hrvatska internetska enciklopedija
Prijeđi na navigaciju Prijeđi na pretraživanje
preuzeto s hr.wikipedije
 
mNema sažetka uređivanja
 
Nisu prikazane 2 međuinačice
Redak 1: Redak 1:
local p = {}
local p = {}
local HTMLcolor = mw.loadData( 'Module:Kontrast boja/boje' )
local HTMLcolor = mw.loadData('Modul:Kontrast_boja/boje')


local function sRGB (v)
-- lokalni cache za HEX u glavnom modulu
if (v <= 0.03928) then
local hexCache = {}
v = v / 12.92
 
else
local function sRGB(v)
v = math.pow((v+0.055)/1.055, 2.4)
    if v <= 0.03928 then
end
        return v / 12.92
return v
    else
        return ((v + 0.055) / 1.055) ^ 2.4
    end
end
end


local function rgbdec2lum(R, G, B)
local function rgbdec2lum(R, G, B)
if ( 0 <= R and R < 256 and 0 <= G and G < 256 and 0 <= B and B < 256 ) then
    if R and G and B and R>=0 and R<256 and G>=0 and G<256 and B>=0 and B<256 then
return 0.2126 * sRGB(R/255) + 0.7152 * sRGB(G/255) + 0.0722 * sRGB(B/255)
        return 0.2126 * sRGB(R/255) + 0.7152 * sRGB(G/255) + 0.0722 * sRGB(B/255)
else
    end
return ''
    return nil
end
end
end


local function hsl2lum(h, s, l)
local function hex2lum(hex)
if ( 0 <= h and h < 360 and 0 <= s and s <= 1 and 0 <= l and l <= 1 ) then
    hex = hex:lower():gsub("^#", "")
local c = (1 - math.abs(2*l - 1))*s
    if hexCache[hex] then
local x = c*(1 - math.abs( math.fmod(h/60, 2) - 1) )
        return hexCache[hex]
local m = l - c/2
    end
 
    local r,g,b
    if #hex == 3 then
        r = tonumber(hex:sub(1,1)..hex:sub(1,1), 16)
        g = tonumber(hex:sub(2,2)..hex:sub(2,2), 16)
        b = tonumber(hex:sub(3,3)..hex:sub(3,3), 16)
    elseif #hex == 6 then
        r = tonumber(hex:sub(1,2), 16)
        g = tonumber(hex:sub(3,4), 16)
        b = tonumber(hex:sub(5,6), 16)
    else
        return nil
    end


local r, g, b = m, m, m
    local L = rgbdec2lum(r, g, b)
if( 0 <= h and h < 60 ) then
    hexCache[hex] = L
r = r + c
    return L
g = g + x
elseif( 60 <= h and h < 120 ) then
r = r + x
g = g + c
elseif( 120 <= h and h < 180 ) then
g = g + c
b = b + x
elseif( 180 <= h and h < 240 ) then
g = g + x
b = b + c
elseif( 240 <= h and h < 300 ) then
r = r + x
b = b + c
elseif( 300 <= h and h < 360 ) then
r = r + c
b = b + x
end
return rgbdec2lum(255*r, 255*g, 255*b)
else
return ''
end
end
end


local function color2lum(c)
local function hsl2lum(h, s, l)
    if not (h and s and l) then return nil end
    local c = (1 - math.abs(2*l - 1)) * s
    local x = c * (1 - math.abs((h/60)%2 - 1))
    local m = l - c/2
    local r,g,b = m,m,m


if (c == nil) then
    if h < 60 then r=r+c; g=g+x
return ''
    elseif h < 120 then r=r+x; g=g+c
end
    elseif h < 180 then g=g+c; b=b+x
    elseif h < 240 then g=g+x; b=b+c
    elseif h < 300 then r=r+x; b=b+c
    else r=r+c; b=b+x end


-- html '#' entity
    return rgbdec2lum(255*r, 255*g, 255*b)
c = c:gsub("&#35;", "#")
end


-- whitespace
local function color2lum(c)
c = c:match( '^%s*(.-)[%s;]*$' )
    if not c then return nil end
 
-- unstrip nowiki strip markers
c = mw.text.unstripNoWiki(c)


-- lowercase
    c = mw.text.unstripNoWiki(c):lower():gsub("&#35;", "#"):match("^%s*(.-)%s*$")
c = c:lower()


-- first try to look it up
    -- 1) ime boje
local L = HTMLcolor[c]
    if HTMLcolor[c] then
if (L ~= nil) then
        return HTMLcolor[c]
return L
    end
end


-- convert from hsl
    -- 2) HEX
if mw.ustring.match(c,'^hsl%([%s]*[0-9][0-9%.]*[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*%)$') then
    local hex = c:match("^#?([a-f0-9]+)$")
local h, s, l = mw.ustring.match(c,'^hsl%([%s]*([0-9][0-9%.]*)[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*%)$')
    if hex then
return hsl2lum(tonumber(h), tonumber(s)/100, tonumber(l)/100)
        return hex2lum(hex)
end
    end


-- convert from rgb
    -- 3) rgb()
if mw.ustring.match(c,'^rgb%([%s]*[0-9][0-9]*[%s]*,[%s]*[0-9][0-9]*[%s]*,[%s]*[0-9][0-9]*[%s]*%)$') then
    local R,G,B = c:match("^rgb%(%s*(%d+)%s*,%s*(%d+)%s*,%s*(%d+)%s*%)$")
local R, G, B = mw.ustring.match(c,'^rgb%([%s]*([0-9][0-9]*)[%s]*,[%s]*([0-9][0-9]*)[%s]*,[%s]*([0-9][0-9]*)[%s]*%)$')
    if R then
return rgbdec2lum(tonumber(R), tonumber(G), tonumber(B))
        return rgbdec2lum(tonumber(R), tonumber(G), tonumber(B))
end
    end


-- convert from rgb percent
    -- 4) rgb%()
if mw.ustring.match(c,'^rgb%([%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*%)$') then
    local Rp,Gp,Bp = c:match("^rgb%(%s*([%d%.]+)%%%s*,%s*([%d%.]+)%%%s*,%s*([%d%.]+)%%%s*%)$")
local R, G, B = mw.ustring.match(c,'^rgb%([%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*%)$')
    if Rp then
return rgbdec2lum(255*tonumber(R)/100, 255*tonumber(G)/100, 255*tonumber(B)/100)
        return rgbdec2lum(255*Rp/100, 255*Gp/100, 255*Bp/100)
end
    end


-- remove leading # (if there is one) and whitespace
    -- 5) hsl()
c = mw.ustring.match(c, '^[%s#]*([a-f0-9]*)[%s]*$')
    local h,s,l = c:match("^hsl%(%s*([%d%.]+)%s*,%s*([%d%.]+)%%%s*,%s*([%d%.]+)%%%s*%)$")
    if h then
        return hsl2lum(tonumber(h), tonumber(s)/100, tonumber(l)/100)
    end


-- split into rgb
    return nil
local cs = mw.text.split(c or '', '')
if( #cs == 6 ) then
local R = 16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[2])
local G = 16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[4])
local B = 16*tonumber('0x' .. cs[5]) + tonumber('0x' .. cs[6])
 
return rgbdec2lum(R, G, B)
elseif ( #cs == 3 ) then
local R = 16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[1])
local G = 16*tonumber('0x' .. cs[2]) + tonumber('0x' .. cs[2])
local B = 16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[3])
 
return rgbdec2lum(R, G, B)
end
 
-- failure, return blank
return ''
end
end


-- This exports the function for use in other modules.
-- The colour is passed as a string.
function p._lum(color)
function p._lum(color)
return color2lum(color)
    return color2lum(color)
end
end


function p._jacikontrast(args)
function p._jacikontrast(args)
local bias = tonumber(args['bias'] or '0') or 0
    local bias = tonumber(args.bias or 0) or 0
local css = (args['css'] and args['css'] ~= '') and true or false
    local css = args.css and args.css ~= ""
local v1 = color2lum(args[1] or '')
 
local c2 = args[2] or '#FFFFFF'
    local c1 = args[1] or ""
local v2 = color2lum(c2)
    local c2 = args[2] or "#ffffff"
local c3 = args[3] or '#000000'
    local c3 = args[3] or "#000000"
local v3 = color2lum(c3)
local ratio1 = -1;
local ratio2 = -1;
if (type(v1) == 'number' and type(v2) == 'number') then
ratio1 = (v2 + 0.05)/(v1 + 0.05)
ratio1 = (ratio1 < 1) and 1/ratio1 or ratio1
end
if (type(v1) == 'number' and type(v3) == 'number') then
ratio2 = (v3 + 0.05)/(v1 + 0.05)
ratio2 = (ratio2 < 1) and 1/ratio2 or ratio2
end


if css then
    local v1 = color2lum(c1)
local c1 = args[1] or ''
    local v2 = color2lum(c2)
if mw.ustring.match(c1, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]$') or
    local v3 = color2lum(c3)
mw.ustring.match(c1, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]$') then
c1 = '#' .. c1
end
if mw.ustring.match(c2, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]$') or
mw.ustring.match(c2, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]$') then
c2 = '#' .. c2
end
if mw.ustring.match(v3, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]$') or
mw.ustring.match(v3, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]$') then
c3 = '#' .. c3
end
return 'background-color:' .. c1 .. '; color:' .. ((ratio1 > 0) and (ratio2 > 0) and ((ratio1 + bias > ratio2) and c2 or c3) or '') .. ';'
end


return (ratio1 > 0) and (ratio2 > 0) and ((ratio1 + bias > ratio2) and c2 or c3) or ''
    if not (v1 and v2 and v3) then
end
        return css and "" or ""
    end


function p._ratio(args)
    local r1 = (v2+0.05)/(v1+0.05)
local v1 = color2lum(args[1])
    local r2 = (v3+0.05)/(v1+0.05)
local v2 = color2lum(args[2])
    if r1 < 1 then r1 = 1/r1 end
if (type(v1) == 'number' and type(v2) == 'number') then
    if r2 < 1 then r2 = 1/r2 end
-- v1 should be the brighter of the two.
if v2 > v1 then
v1, v2 = v2, v1
end
return (v1 + 0.05)/(v2 + 0.05)
else
return args['error'] or '?'
end
end


function p._styleratio(args)
    local best = (r1 + bias > r2) and c2 or c3
local style = (args[1] or ''):lower()
local bg, fg = 'white', 'black'
local lum_bg, lum_fg = 1, 0


if args[2] then
    if css then
local lum = color2lum(args[2])
        return string.format("background-color:%s; color:%s;", c1, best)
if lum ~= '' then bg, lum_bg = args[2], lum end
    end
end
if args[3] then
local lum = color2lum(args[3])
if lum ~= '' then fg, lum_fg = args[3], lum end
end


local slist = mw.text.split(mw.ustring.gsub(mw.ustring.gsub(style or '', '&#[Xx]23;', '#'), '&#35;', '#'), ';')
    return best
for k = 1,#slist do
local s = slist[k]
local k,v = s:match( '^[%s]*([^:]-):([^:]-)[%s;]*$' )
k = k or ''
v = v or ''
if (k:match('^[%s]*(background)[%s]*$') or k:match('^[%s]*(background%-color)[%s]*$')) then
local lum = color2lum(v)
if( lum ~= '' ) then bg, lum_bg = v, lum end
elseif (k:match('^[%s]*(color)[%s]*$')) then
local lum = color2lum(v)
if( lum ~= '' ) then bg, lum_fg = v, lum end
end
end
if lum_bg > lum_fg then
return (lum_bg + 0.05)/(lum_fg + 0.05)
else
return (lum_fg + 0.05)/(lum_bg + 0.05)
end
end
end


--[[
Use {{#invoke:Kontrast boja|somecolor}} directly or
{{#invoke:Kontrast boja}} from a wrapper template.
Parameters:
-- |1= — required; A color to check.
--]]
function p.lum(frame)
function p.lum(frame)
local color = frame.args[1] or frame:getParent().args[1]
    local color = frame.args[1] or frame:getParent().args[1]
return p._lum(color)
    return p._lum(color) or ''
end
end


function p.ratio(frame)
function p.ratio(frame)
local args = frame.args[1] and frame.args or frame:getParent().args
    local args = frame.args[1] and frame.args or frame:getParent().args
return p._ratio(args)
    local v1 = color2lum(args[1])
end
    local v2 = color2lum(args[2])
 
    if v1 and v2 then
function p.styleratio(frame)
        if v2 > v1 then v1, v2 = v2, v1 end
local args = frame.args[1] and frame.args or frame:getParent().args
        return (v1 + 0.05)/(v2 + 0.05)
return p._styleratio(args)
    end
    return args.error or '?'
end
end


function p.jacikontrast(frame)
function p.jacikontrast(frame)
local args = frame.args[1] and frame.args or frame:getParent().args
    local args = frame.args[1] and frame.args or frame:getParent().args
return p._jacikontrast(args)
    return p._jacikontrast(args)
end
end


return p
return p

Posljednja izmjena od 15. travanj 2026. u 09:58

Dokumentacija modula
== Korištenje ==

To compute relative luminescence

{{ColorToLum|color}} or {{#invoke:Color contrast|lum|color}}

To compute a contrast ratio between two colors

{{Color contrast ratio|color1|color2|error=?}} or {{#invoke:Color contrast|ratio|color1|color2|error=?}}

To determine which of two colors (color2a and color2b) has the greater contrast ratio with a particular color (color1)

{{Greater color contrast ratio|color1|color2a|color2b}} or {{#invoke:Color contrast|greatercontrast|color1|color2a|color2b}}

To compute the contrast ratio between the background and text colors specified in a css style string

{{#invoke:Color contrast|styleratio|css style statement string|default background color|default text color}}


local p = {}
local HTMLcolor = mw.loadData('Modul:Kontrast_boja/boje')

-- lokalni cache za HEX u glavnom modulu
local hexCache = {}

local function sRGB(v)
    if v <= 0.03928 then
        return v / 12.92
    else
        return ((v + 0.055) / 1.055) ^ 2.4
    end
end

local function rgbdec2lum(R, G, B)
    if R and G and B and R>=0 and R<256 and G>=0 and G<256 and B>=0 and B<256 then
        return 0.2126 * sRGB(R/255) + 0.7152 * sRGB(G/255) + 0.0722 * sRGB(B/255)
    end
    return nil
end

local function hex2lum(hex)
    hex = hex:lower():gsub("^#", "")
    if hexCache[hex] then
        return hexCache[hex]
    end

    local r,g,b
    if #hex == 3 then
        r = tonumber(hex:sub(1,1)..hex:sub(1,1), 16)
        g = tonumber(hex:sub(2,2)..hex:sub(2,2), 16)
        b = tonumber(hex:sub(3,3)..hex:sub(3,3), 16)
    elseif #hex == 6 then
        r = tonumber(hex:sub(1,2), 16)
        g = tonumber(hex:sub(3,4), 16)
        b = tonumber(hex:sub(5,6), 16)
    else
        return nil
    end

    local L = rgbdec2lum(r, g, b)
    hexCache[hex] = L
    return L
end

local function hsl2lum(h, s, l)
    if not (h and s and l) then return nil end
    local c = (1 - math.abs(2*l - 1)) * s
    local x = c * (1 - math.abs((h/60)%2 - 1))
    local m = l - c/2
    local r,g,b = m,m,m

    if h < 60 then r=r+c; g=g+x
    elseif h < 120 then r=r+x; g=g+c
    elseif h < 180 then g=g+c; b=b+x
    elseif h < 240 then g=g+x; b=b+c
    elseif h < 300 then r=r+x; b=b+c
    else r=r+c; b=b+x end

    return rgbdec2lum(255*r, 255*g, 255*b)
end

local function color2lum(c)
    if not c then return nil end

    c = mw.text.unstripNoWiki(c):lower():gsub("&#35;", "#"):match("^%s*(.-)%s*$")

    -- 1) ime boje
    if HTMLcolor[c] then
        return HTMLcolor[c]
    end

    -- 2) HEX
    local hex = c:match("^#?([a-f0-9]+)$")
    if hex then
        return hex2lum(hex)
    end

    -- 3) rgb()
    local R,G,B = c:match("^rgb%(%s*(%d+)%s*,%s*(%d+)%s*,%s*(%d+)%s*%)$")
    if R then
        return rgbdec2lum(tonumber(R), tonumber(G), tonumber(B))
    end

    -- 4) rgb%()
    local Rp,Gp,Bp = c:match("^rgb%(%s*([%d%.]+)%%%s*,%s*([%d%.]+)%%%s*,%s*([%d%.]+)%%%s*%)$")
    if Rp then
        return rgbdec2lum(255*Rp/100, 255*Gp/100, 255*Bp/100)
    end

    -- 5) hsl()
    local h,s,l = c:match("^hsl%(%s*([%d%.]+)%s*,%s*([%d%.]+)%%%s*,%s*([%d%.]+)%%%s*%)$")
    if h then
        return hsl2lum(tonumber(h), tonumber(s)/100, tonumber(l)/100)
    end

    return nil
end

function p._lum(color)
    return color2lum(color)
end

function p._jacikontrast(args)
    local bias = tonumber(args.bias or 0) or 0
    local css = args.css and args.css ~= ""

    local c1 = args[1] or ""
    local c2 = args[2] or "#ffffff"
    local c3 = args[3] or "#000000"

    local v1 = color2lum(c1)
    local v2 = color2lum(c2)
    local v3 = color2lum(c3)

    if not (v1 and v2 and v3) then
        return css and "" or ""
    end

    local r1 = (v2+0.05)/(v1+0.05)
    local r2 = (v3+0.05)/(v1+0.05)
    if r1 < 1 then r1 = 1/r1 end
    if r2 < 1 then r2 = 1/r2 end

    local best = (r1 + bias > r2) and c2 or c3

    if css then
        return string.format("background-color:%s; color:%s;", c1, best)
    end

    return best
end

function p.lum(frame)
    local color = frame.args[1] or frame:getParent().args[1]
    return p._lum(color) or ''
end

function p.ratio(frame)
    local args = frame.args[1] and frame.args or frame:getParent().args
    local v1 = color2lum(args[1])
    local v2 = color2lum(args[2])
    if v1 and v2 then
        if v2 > v1 then v1, v2 = v2, v1 end
        return (v1 + 0.05)/(v2 + 0.05)
    end
    return args.error or '?'
end

function p.jacikontrast(frame)
    local args = frame.args[1] and frame.args or frame:getParent().args
    return p._jacikontrast(args)
end

return p