Danila Asked:2022-09-22 20:14:44 +0000 UTC2022-09-22 20:14:44 +0000 UTC 2022-09-22 20:14:44 +0000 UTC 如果知道现有颜色的透明度,是否可以知道原始颜色? 772 有一块蓝色的阴影: ColorPic 将其代码定义为#4493b1或rgba(68, 147, 177, 1)。但可以肯定的是,这种颜色是由于赋予透明度(opacity: 0.7)而获得的。同时,这个方块位于body的背景之上#dfe2d9。 有没有办法找出原始颜色代码?有公式吗?或者一些允许你这样做的服务? html 1 个回答 Voted Best Answer yar85 2022-09-24T11:26:43Z2022-09-24T11:26:43Z 公式(每个颜色通道单独计算): X R,G,B = (mixColor R,G,B - knownColor R,G,B × knownColor opacity ) ÷ X opacity 它是在学校教授的普通数学基础上获得的。我看不出方程式有问题(只有两个简单的转移),但是如果您仍然对公式有疑问 - 在评论中。也欢迎数学家的批评:) 正如您可能猜到的,此公式仅适用于加色模型。也就是说,对于发射光(显示器上的颜色) - 但不适用于反射/折射(物理对象的颜色、各种 YRB、CMYK 等)。 非常简单的计算器,仅用于检查: const [bgInp, mixInp, opcInp] = document.querySelectorAll('input'), outputEl = document.querySelector('#result'); const inputHandler = () => { // установка цвета контейнеров по значению дочернего инпута [bgInp, mixInp].forEach(inp => setColor(inp.parentElement, inp.value)); // преобразование значений инпутов в числовые (r, g, b, и их "вес" по opacity) const bgClr = hexColorToObj(bgInp.value), mixClr = hexColorToObj(mixInp.value), mixWeight = Math.min(1, Math.max(0, +opcInp.value || 1)), bgWeight = 1 - mixWeight; // вычисление искомого цвета const result = ['r', 'g', 'b'].reduce((rslt, chnl) => ( rslt += toByteHex((mixClr[chnl] - bgClr[chnl] * bgWeight) / mixWeight) ), '#'); // скрытие/показ элемента с результатом, по наличию ошибок const hasError = document.querySelector(':invalid') || !/^#[a-f\d]{6}$/.test(result); document.body.classList.toggle('has-error', hasError); if (hasError) return; // вывод результата [...outputEl.children].forEach((el, idx) => { setColor(el, !idx ? result : result + toByteHex(255 * mixWeight)); }); }; // добавление обработчика, и его вызов для инициализации for (const inp of [bgInp, mixInp, opcInp]) inp.addEventListener('input', inputHandler); inputHandler(); // вспомогательные функции function setColor(el, clr) { el.style.background = el.dataset.clr = clr; } function hexColorToObj(hexColor) { const [r, g, b] = hexColor.slice(1).padStart(6, '0').match(/../g).map(v => parseInt(v, 16)); return { r, g, b }; } function toByteHex(num) { return Math.round(num).toString(16).padStart(2, '0'); } * { position: relative; box-sizing: border-box; margin: 0; padding: 0; font: 1.125rem monospace; } :invalid { border-color: #d44; color: #d44; } div { width: 32ch; max-width: 100%; margin: 0.5em 0 0; padding: 0.5em; } input { width: 9ch; padding: 0.2em 0.3em; border: 2px solid transparent; outline: 1px solid #fff; } #result { display: flex; height: 2.5em; margin: 0; padding: 0; } #result > span { flex: 1 1; padding: 0.5em; } #result > span::before { content: '🎯 ' attr(data-clr); display: inline; color: #fff; mix-blend-mode: difference; } #result > :last-child::before { content: 'Проверка'; } #result > :last-child::after { content: '◯\a⇅\a◯'; position: absolute; top: -0.1em; right: 0.3em; transform: translateY(-50%); font: 1.2em/1 monospace; white-space: pre; opacity: 0.3; } .has-error #result { visibility: hidden !important; } <div> <input value="#dfe2d9" pattern="#[a-f\d]{6}"> <div> <input value="#4493b1" pattern="#[a-f\d]{6}"> <input value="0.7" type="number" min="0.01" max="1" step="0.01"> </div> <div id="result"> <span></span> <span></span> </div> </div> 对于格式不正确的总计,计算器只是隐藏了结果——也就是说,它不正确输入,不从短的 3 字符十六进制和 rgba/hsl 转换,也不计算最小值。混合颜色的不透明度。
公式(每个颜色通道单独计算):
它是在学校教授的普通数学基础上获得的。我看不出方程式有问题(只有两个简单的转移),但是如果您仍然对公式有疑问 - 在评论中。也欢迎数学家的批评:)
正如您可能猜到的,此公式仅适用于加色模型。也就是说,对于发射光(显示器上的颜色) - 但不适用于反射/折射(物理对象的颜色、各种 YRB、CMYK 等)。
非常简单的计算器,仅用于检查:
对于格式不正确的总计,计算器只是隐藏了结果——也就是说,它不正确输入,不从短的 3 字符十六进制和 rgba/hsl 转换,也不计算最小值。混合颜色的不透明度。