- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
作为这个问题的后续:( How can I draw legible text on a bitmap (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]。如何向每个部分“添加”足够的内容以实现这两个差异?
编辑:具体来说,我的困惑在于:
看起来我需要添加三个单独的值(R、G、B)以实现两个不同的目标(新 RGB 加起来为原始加 125,新 RGB 加起来为原始加 500
看起来我可能需要“加权”我添加的亮度值,以便为 G 添加比 R 多于 B 的亮度值。
我不知道如何解决#1。我不确定我对 #2 的看法是否正确。
编辑:建议的解决方案
我目前正在试验这个:
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 色差”完全是废话,零个已知颜色符合条件)并进行实验。
支持代码:
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;
}
最佳答案
这更像是对原始问题的回答。我称之为自制大纲。
使用透明度加上你可以获得的最大和最小亮度(白色和黑色)它创造了良好的对比度,至少它在我的屏幕上看起来相当不错。
它是阴影和透明度的混合体。我从红色成分中减去一点以获得您想要的浅绿色..
它首先通过向左上方 1 个像素和向右下方 1 个像素打印文本来创建背景的较暗版本。最后它在上面打印一个明亮的版本。请注意,它并没有真正使用黑色和白色,因为它的半透明像素的色调实际上是每个背景像素的色调。
对于实际的打印输出,您必须进行试验,尤其是字体以及两个透明胶片!
此外,您还应该根据打印点的亮度在黑色阴影上的白色和白色高光上的黑色之间切换。但是有了这个 homemeade 轮廓,它确实可以在黑暗和明亮的背景上工作,只是在明亮的背景上看起来会少一些优雅。
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 对象及其使用 block G 将被简单地替换为 e.Graphics 事件参数..
我注意到您使用“透明”标签来显示数据以避免 Graphics.DrawString 和 Paint 事件的细节。
好吧,这是可以做到的,结果看起来很相似:
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 中拥有真正透明的控件,我们需要一些额外的努力。您可能使用这样的标签子类:
public partial class trLabel : Label
{
public trLabel()
{
SetStyle(ControlStyles.SupportsTransparentBackColor | ControlStyles.UserPaint, true);
BackColor = Color.Transparent;
Visible = true;
AutoSize = true;
}
}
这似乎可行。但实际上它只是看起来那样,因为在创建时每个标签都会从其父标签获取其当前背景的副本。永远不会更新。这就是为什么我必须将第二个和第三个标签添加到我显示图像的图片框中,而不是添加到第一个和第二个分别为“透明”标签。
除非您自己绘制,否则 Winforms 控件之间根本就没有真正的透明度。
所以 DrawString 解决方案并不复杂。它给你带来的好处是允许你扭曲 Graphics 对象的几个属性,比如 Smoothingmode。 , TextContrast或 InterpolationMode
关于c# - 我如何实现这个 "color difference"算法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25068189/
背景: 我最近一直在使用 JPA,我为相当大的关系数据库项目生成持久层的轻松程度给我留下了深刻的印象。 我们公司使用大量非 SQL 数据库,特别是面向列的数据库。我对可能对这些数据库使用 JPA 有一
我已经在我的 maven pom 中添加了这些构建配置,因为我希望将 Apache Solr 依赖项与 Jar 捆绑在一起。否则我得到了 SolarServerException: ClassNotF
interface ITurtle { void Fight(); void EatPizza(); } interface ILeonardo : ITurtle {
我希望可用于 Java 的对象/关系映射 (ORM) 工具之一能够满足这些要求: 使用 JPA 或 native SQL 查询获取大量行并将其作为实体对象返回。 允许在行(实体)中进行迭代,并在对当前
好像没有,因为我有实现From for 的代码, 我可以转换 A到 B与 .into() , 但同样的事情不适用于 Vec .into()一个Vec . 要么我搞砸了阻止实现派生的事情,要么这不应该发
在 C# 中,如果 A 实现 IX 并且 B 继承自 A ,是否必然遵循 B 实现 IX?如果是,是因为 LSP 吗?之间有什么区别吗: 1. Interface IX; Class A : IX;
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我正在阅读标准haskell库的(^)的实现代码: (^) :: (Num a, Integral b) => a -> b -> a x0 ^ y0 | y0 a -> b ->a expo x0
我将把国际象棋游戏表示为 C++ 结构。我认为,最好的选择是树结构(因为在每个深度我们都有几个可能的移动)。 这是一个好的方法吗? struct TreeElement{ SomeMoveType
我正在为用户名数据库实现字符串匹配算法。我的方法采用现有的用户名数据库和用户想要的新用户名,然后检查用户名是否已被占用。如果采用该方法,则该方法应该返回带有数据库中未采用的数字的用户名。 例子: “贾
我正在尝试实现 Breadth-first search algorithm , 为了找到两个顶点之间的最短距离。我开发了一个 Queue 对象来保存和检索对象,并且我有一个二维数组来保存两个给定顶点
我目前正在 ika 中开发我的 Python 游戏,它使用 python 2.5 我决定为 AI 使用 A* 寻路。然而,我发现它对我的需要来说太慢了(3-4 个敌人可能会落后于游戏,但我想供应 4-
我正在寻找 Kademlia 的开源实现C/C++ 中的分布式哈希表。它必须是轻量级和跨平台的(win/linux/mac)。 它必须能够将信息发布到 DHT 并检索它。 最佳答案 OpenDHT是
我在一本书中读到这一行:-“当我们要求 C++ 实现运行程序时,它会通过调用此函数来实现。” 而且我想知道“C++ 实现”是什么意思或具体是什么。帮忙!? 最佳答案 “C++ 实现”是指编译器加上链接
我正在尝试使用分支定界的 C++ 实现这个背包问题。此网站上有一个 Java 版本:Implementing branch and bound for knapsack 我试图让我的 C++ 版本打印
在很多情况下,我需要在 C# 中访问合适的哈希算法,从重写 GetHashCode 到对数据执行快速比较/查找。 我发现 FNV 哈希是一种非常简单/好/快速的哈希算法。但是,我从未见过 C# 实现的
目录 LRU缓存替换策略 核心思想 不适用场景 算法基本实现 算法优化
1. 绪论 在前面文章中提到 空间直角坐标系相互转换 ,测绘坐标转换时,一般涉及到的情况是:两个直角坐标系的小角度转换。这个就是我们经常在测绘数据处理中,WGS-84坐标系、54北京坐标系
在软件开发过程中,有时候我们需要定时地检查数据库中的数据,并在发现新增数据时触发一个动作。为了实现这个需求,我们在 .Net 7 下进行一次简单的演示. PeriodicTimer .
二分查找 二分查找算法,说白了就是在有序的数组里面给予一个存在数组里面的值key,然后将其先和数组中间的比较,如果key大于中间值,进行下一次mid后面的比较,直到找到相等的,就可以得到它的位置。
我是一名优秀的程序员,十分优秀!