Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何实现这个“色差”算法?

如何实现这个“色差”算法?
EN

Stack Overflow用户
提问于 2014-07-31 12:19:14
回答 2查看 760关注 0票数 2

作为这个问题的后续:(如何在位图(Winforms)上绘制清晰的文本?),通过计算文本下面的“平均”颜色,并为文本选择适当的对比颜色,我在位图上绘制可读但小的文本。

我从https://stackoverflow.com/a/6185448/3784949窃取了Till的代码,用于计算“平均”bmp颜色。现在我来看看http://www.w3.org/TR/AERT#color-contrast提出的“色差”算法。

这意味着我需要使我的颜色亮度至少增加125个“单位”,而我的色差至少要大500个单位,其中亮度和差值计算如下:

颜色亮度由以下公式决定:

((红色值X 299) +(绿色值X 587) +(蓝色值X 114)) / 1000

色差由下列公式决定:

(最大(红色值1,红色值2) -最小值(红色值1,红色值2)) +(最大值(绿色值1,绿色值2) -最小值(绿色值1,绿色值2)) +(最大值(蓝色值1,蓝色值2) -最小值(蓝色值1,蓝色值2))

我如何实现这一点?我可以用ARGB来设置我的颜色(我相信,这是一个标签的前景色);但是我如何计算出如何改变每个单独的值来达到这里所需的差异呢?我不熟悉将“差异”单元分解成它们的组成部分所需的数学。

例如,一个位图的“平均值”是: A=255、R=152、G=138、B=129。我如何“添加”到每个部分,以实现这两个差异?

编辑:具体来说,我的困惑在于:

  1. 看起来我需要添加三个独立的值(R,G,B)来实现两个不同的目标(新的RGB加到原来的加125,新的RGB加到原来的加500。
  2. 看来,我可能需要“加权”我增加的亮度值,以增加G比R比B更多。

我不知道如何称呼第一位,我也不确定我对第二位的看法是正确的。

编辑:建议的解决方案

我目前正在做这个实验:

代码语言:javascript
运行
AI代码解释
复制
private Color GetContrastingFontColor(Color AverageColorOfBitmap,
                                      List<Color> FavoriteColors)
{
    IEnumerable<Color> AcceptableColors =
        (IEnumerable<Color>)FavoriteColors.Where(clr =>
        (GetColorDifferenceAboveTarget(AverageColorOfBitmap, clr, (float)200) > 0)
        && (GetBrightnessAboveTarget(AverageColorOfBitmap, clr, (float).125) > 0))
        .OrderBy(clr => GetColorDifferenceAboveTarget(
                            AverageColorOfBitmap, clr, (float)200));
    return AcceptableColors.DefaultIfEmpty(Color.Aqua).First();
}

这是一个很好的框架,但我需要努力从列表中选择“最好”的候选人。现在,它只是返回“符合亮度标准的最大色差的合格颜色”。然而,这允许我修改浮点值(W3的"500色差要求“是完全的废话,零KnownColors限定)和实验。

支持代码:

代码语言:javascript
运行
AI代码解释
复制
private float GetBrightnessAboveTarget(Color AverageColorOfBitmap, 
                                       Color proposed, float desiredDifference)
{
    float result = proposed.GetBrightness() - AverageColorOfBitmap.GetBrightness();
    return result - desiredDifference;
}

private float GetColorDifferenceAboveTarget(Color avg, Color proposed,
                                            float desiredDifference)
{
    float r1 = Convert.ToSingle(MaxByte(Color.Red, avg, proposed));
    float r2 = Convert.ToSingle(MinByte(Color.Red, avg, proposed));
    float r3 = Convert.ToSingle(MaxByte(Color.Green, avg, proposed));
    float r4 = Convert.ToSingle(MinByte(Color.Green, avg, proposed));
    float r5 = Convert.ToSingle(MaxByte(Color.Blue, avg, proposed));
    float r6 = Convert.ToSingle(MinByte(Color.Blue, avg, proposed));

    float result = (r1 - r2) + (r3 - r4) + (r5 - r6);
    return result - desiredDifference;
}

private byte MaxByte(Color rgb, Color x, Color y)
{
    if (rgb == Color.Red) return (x.R >= y.R) ? x.R : y.R;
    if (rgb == Color.Green) return (x.G >= y.G) ? x.G : y.G;
    if (rgb == Color.Blue) return (x.B >= y.B) ? x.B : y.B;
    return byte.MinValue;
}

private byte MinByte(Color rgb, Color x, Color y)
{
    if (rgb == Color.Red) return (x.R <= y.R) ? x.R : y.R;
    if (rgb == Color.Green) return (x.G <= y.G) ? x.G : y.G;
    if (rgb == Color.Blue) return (x.B <= y.B) ? x.B : y.B;
    return byte.MinValue;
}
EN

回答 2

Stack Overflow用户

发布于 2014-07-31 15:07:14

这更多的是对原来问题的回答。我称它为主页大纲

使用透明度加上你可以得到的最大和最小亮度(白色和黑色),它创造了良好的对比度,至少在我的屏幕上看起来不错。

这是一种阴影和透明度的混合。我从红色的成分中减去一点点,得到你想要的水.

它首先通过打印左上1像素和右1像素的文本创建一个更暗的背景版本。最后,它在上面打印一个明亮的版本。请注意,它不是真正使用黑白,因为它的半透明像素,色调,它真正的每个背景像素。

对于一个实际的打印输出,您将不得不试验,特别是字体,但也与两个透明!

此外,你也许应该在黑色阴影上的白色和白色高亮点上的黑色之间切换,这取决于你打印的地点的亮度。但有了这个归家的轮廓,它真的将工作在黑暗和明亮的背景,它将只是看起来不那么优雅在一个明亮的背景。

代码语言:javascript
运行
AI代码解释
复制
using (Graphics G = Graphics.FromImage(pictureBox1.Image) )
{
  Font F = new Font("Arial", 8);
  SolidBrush brush0 = new SolidBrush(Color.FromArgb(150, 0, 0, 0))
  SolidBrush brush1 = new SolidBrush(Color.FromArgb(200, 255, 255, 222))

  G.DrawString(textBox1.Text, F, brush0 , new Point(x-1, y-1));
  G.DrawString(textBox1.Text, F, brush0 , new Point(x+1, y+1));
  G.DrawString(textBox1.Text, F, brush1, new Point(x, y));
}

编辑:这是从一个按钮点击调用,但实际上应该在油漆事件。在那里,Graphics对象及其使用块G将被简单的e.Graphics事件参数替换。

我注意到您正在使用“透明”标签来显示数据,以避免Graphics.DrawString和data事件的详细信息。

好吧,这是可以做到的,结果看起来也很相似:

代码语言:javascript
运行
AI代码解释
复制
string theText ="123 - The quick brown fox..";
Label L1, L2, L3;

pictureBox1.Controls.Add(new trLabel());
L1 = (trLabel)pictureBox1.Controls[pictureBox1.Controls.Count - 1];
L1.Text = theText;
L1.ForeColor = Color.FromArgb(150, 0, 0, 0);
L1.Location = new Point(231, 31);  // <- position in the image, change!

L1.Controls.Add(new trLabel());
L2 = (trLabel)L1.Controls[pictureBox1.Controls.Count - 1];
L2.Text = theText;
L2.ForeColor = Color.FromArgb(150, 0, 0, 0);
L2.Location = new Point(2, 2);  // do not change relative postion in the 1st label!

L2.Controls.Add(new trLabel());
L3 = (trLabel)L2.Controls[pictureBox1.Controls.Count - 1];
L3.Text = theText;
L3.ForeColor = Color.FromArgb(200, 255, 255, 234);
L3.Location = new Point(-1,-1);  // do not change relative postion in the 2nd label!

但是,您将注意到,由于在Winforms中不可能有真正的透明控件,我们需要做一些额外的工作。您可能使用的标签子类如下:

代码语言:javascript
运行
AI代码解释
复制
public partial class trLabel : Label
{
    public trLabel()
    {
        SetStyle(ControlStyles.SupportsTransparentBackColor | ControlStyles.UserPaint, true);
        BackColor = Color.Transparent;
        Visible = true;
        AutoSize = true;
    }
}

这似乎很管用。但在现实中,似乎只有这样,因为每个标签在创建时都会从其父标签中获取其当前背景的副本。从来没有更新过。这就是为什么我必须添加第二和第三标签,而不是我显示的图片框,而是第一和第二‘透明’标签。

除非您自己画东西,否则Winforms控件之间就没有真正的透明度。

因此,DrawString解决方案并不是很复杂。它给了您额外的好处,允许您扭曲图形对象的一些属性,如埋伏模式TextContrastInterpolationMode

票数 0
EN

Stack Overflow用户

发布于 2014-07-31 13:23:46

简短建议:只需使用黑色或白色。

这些算法给出了一个通过的标准,而不是用来确定哪些颜色符合该标准的算法。因此,您必须创建这样一个算法。一个简单的算法是遍历每一种可能的颜色,然后计算色差,然后看看差异是否大于125,如果是这样,就有一个很好的颜色可供使用。更好的是,您可以搜索颜色的最大差异。

但这是愚蠢的--如果我给你的颜色是R=152,G=138,B=129 --你认为与之形成对比的颜色是什么?凭直觉,我猜是0,0,0。我选择了最可能的R值、G值和B值的颜色。如果你给我50,200,75的颜色,我会选择R=255,G=0,B=255。同样的逻辑。所以我的算法是如果R<128选择R= 255,否则选择R= 0。G和B也是一样的。

现在,该算法只选择0或255的RGB值。但如果你不喜欢,现在你需要一个数学定义什么是“漂亮”,我会让你自己来解决这个问题。:-)

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25068189

复制
相关文章
当不使用会话状态时禁用它
并不是所有的应用程序或页都需要针对于具体用户的会话状态,您应该对任何不需要会话状态的应用程序或页禁用会话状态。
Java架构师必看
2021/03/22
5180
你家路由器“有趣”的24小时 | 路由器真的安全吗?(含视频)
想必大家都知道最近美国东海岸地区的网站遭遇了一次大规模的DDoS攻击,此次的攻击导致大量用户无法正常访问网站的服务。 根据安全研究专家的分析结果,此次DDoS攻击主要是由受病毒感染的物联网设备所驱动的
FB客服
2018/02/09
8850
你家路由器“有趣”的24小时 | 路由器真的安全吗?(含视频)
关于数组内元素是否会被改变的思考
项目中双层for循环时,想当然的认为内部局部指针变量的变化会影响外面数组中模型的地址。结果调试后发现,是不对的。
woopDast1
2020/09/04
1.1K0
Python 未来会被取代吗?
开发者社区花了几十年的时间才领略到 Python 迷人之处。但自 2010 年初以来,Python 就一直在蓬勃发展,并最终在受欢迎程度上超越了 C、C#、Java 和 JavaScript。但这种趋势还会持续到什么时候呢?什么时候 Python 最终会被其他编程语言所取代?为什么会被取代?
程序员皮克
2021/12/28
7660
夏日不插电: .ART 域名激发探索本能
探索 .ART 社区里让人心醉的夏季活动,包括冲浪文化、意大利风景以及特拉维夫艺术博物馆独特的艺术夏令营。
腾讯云DNSPod团队
2023/07/24
2100
夏日不插电: .ART 域名激发探索本能
R python在无图形用户界面时保存图片
在用python的matplotlib,和R中自带的作图,如果想保存图片时,当你有图形用户界面时是没有问题的,但是当没有图形用户界面时,会报错: 在R中,解决办法: https://blog.csdn.net/LongBless/article/details/6373291 在python中,解决办法: 在导入matplotlib的其他包之前,写以下语句:   import matplotlib   matplotlib.use('Agg')
Echo_fy
2018/07/06
9850
当flex容器中包含absolute元素时
我们设置了justify-content: center;,不同机型显示区别如下:
celineWong7
2020/11/05
3.8K0
EasyDSS前端用户管理界面分页与页面内容不匹配的优化
EasyDSS视频平台作为一套网页视频流媒体平台,观看视频推流直播不需要安装插件,网页直接即可播放,且近期我们已经更新了系统的内核,在性能上也会有进一步的提升。
TSINGSEE青犀视频
2021/09/13
1.8K0
iOS界面设计,12个优秀案例激发你的灵感
总所周知,iOS和Android是当今两大移动平台,前者采用Human Interface Design,后者采用Material Design。作为设计师,尤其是App设计师,总是会在这两者进行设计。如果你的产品能在井喷的App里推颖而出,这一定会是超级棒的体验。你做到了,设计改变生活。
奔跑的小鹿
2018/02/26
1.8K0
iOS界面设计,12个优秀案例激发你的灵感
你的工作会被AI替代吗?
ChatGPT大杀特杀以后,最常问的问题之一就是能不能替代搜索引擎。最初我的回答是“不能”,现在我的回答同样是“不能”。
木羊
2023/09/09
1560
iOS开启热点或定位时状态栏变化导致布局改变
最近在项目中遇到一种情况就是当其他应用(如百度地图)在使用定位,或者开启手机热点,状态栏会显示"百度地图"正在使用您的位置信息、个人热点:1个连接。并且状态栏将会变为蓝色或红色,导致某些控件的布局下移
BY
2018/05/11
1.7K0
Java会被新兴语言取代吗?
蚌住了!今天被一位初学编程的小伙伴询问:学习JAVA能够干什么? 一时间竟不知从何答起。 近些年的技术圈,单以计算机语言界来说,稳坐第一把太师椅的Java“或将被取代”、迎接转折点、Java项目工程师
老九君
2022/05/25
7690
Java会被新兴语言取代吗?
Java 会被新兴语言取代吗?
8.1、有关通信及网络的大型企业:移动、联通、电信、网通主要的信息化都是Java;
跟着飞哥学编程
2022/11/30
3890
Java 会被新兴语言取代吗?
C++中基类私有成员会被继承吗
在类的继承中,类的私有成员在派生类中是“不可见“的,这种”不可见“是指在派生类的成员函数中,或者通过派生类的对象(指针,引用)不能直接访问它们。但是,不能直接访问并不代表不能访问。在派生类还是能够通过调用基类的共有函数的方式来间接地访问基类的私有成员,包括私有成员变量和私有成员函数。考察如下程序。
恋喵大鲤鱼
2018/08/03
2.4K0
拆不拆?中台的架构合理吗?
每一个新概念的出现 仿佛都带着大干一番的势头 然而,理想美好,现实骨感 …… …… 随着科技加速,各行各业都在热烈地讨论如何完成数字化转型,数字化和智能化的东风席卷中华大地。 自从阿里提出了数据中台,“中台”这个概念就马上成为了国内大多数企业趋之若鹜的风口。 真正实施后发现,很多挑战不是依靠某种技术、工具或平台就可以完全解决的,于是好多机构开始忙着拆中台…… 那么问题出在了那里,中台真的是坑吗? ◆ 首先,什么是中台? 阿里构建数据中台的目标是one data,one service。 不论是数据中台,
博文视点Broadview
2022/03/14
6710
当区块链遇上传统行业 我们的生活和工作会改变吗?
传统行业在互联网时代是失落的,有人调侃道,“全球最大的外卖平台,公司里全是电脑并没有锅碗;全球最大的住宿服务提供商并没有任何房产;剁手党的温床各个电商平台并没有任何零售商品的库存…” 烧钱、掐架、抢用户,合并、跨界、搬大佬。数不尽的互联网招数使众多传统行业摸不着头脑而又岌岌可危。 问题在哪儿?是成本?是信用?是平台化? 随着区块链技术的出现和发展,当区块链突破以金融为主而覆盖渗透进其他行业的时候,我们发现,区块链技术的本质只要从应用途径上拓展一下,就能很大程度促进解决上述传统行业遇见的问题,甚至可以改变
企鹅号小编
2018/01/16
8370
当区块链遇上传统行业 我们的生活和工作会改变吗?
Koa封装改变公共状态的方法
在后端开发中,应交互要求,经常会用到一些改变状态的方法,如收藏与取消收藏、点赞与取消点赞、上架与下架等等,今天给大家分享一个用Koa结合MongoDB封装的改变状态的方法,实现如下:
越陌度阡
2020/11/26
5560
用户登录界面[通俗易懂]
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/166531.html原文链接:https://javaforall.cn
全栈程序员站长
2022/09/20
3.3K0
用户登录界面[通俗易懂]
激发态计算中的溶剂效应
已经有不少小伙伴在催更,非常感谢大家的支持,也有了更新的动力。关于隐式溶剂模型的介绍,可参见《理论计算中的溶剂效应模型》一文。本文着重介绍在激发态计算中使用隐式溶剂模型时的相关要点,为后面介绍荧光和磷光的计算打个基础。
用户7592569
2020/07/27
2.6K0
激发态计算中的溶剂效应
CSS——用户界面
用户界面(User Interface)属性是一些与用户界面特性相关的CSS属性。
Html5知典
2019/11/26
7310

相似问题

无法连接到eclipse中的新SQL Server

22

无法在eclipse中创建新的EJB项目

18

无法在eclipse中创建新的Maven项目

28

无法在eclipse中创建新的android项目

10

无法在Eclipse中创建新的Android项目

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文