【发布时间】:2012-12-31 03:27:39
【问题描述】:
我正在尝试过滤位图图像以增加或减少色相、饱和度和亮度值。
我的代码运行良好,但是速度很慢。
我将两个位图锁定在内存中,即原始源和当前目标。用户可以移动各种 trackbar 控件来修改每个值,然后将其转换为 HSL 值。例如,trackbar 上的值对应的范围是 -1.0 到 1.0。
每次引发跟踪栏值更改的事件时,我都会运行一个函数来锁定目标位图并将 HSL 值应用于源位图,然后将结果存储在目标位图中。完成后,我解锁目标位图并在屏幕上绘制图像。
之前我使用查找表作为我的其他过滤器,因为我正在执行按字节操作。但是我不知道如何使用 HSL 来应用它。这是我正在使用的代码:
byte red, green, blue;
for (int i = 0; i < sourceBytes.Length; i += 3)
{
blue = sourceBytes[i];
green = sourceBytes[i + 1];
red = sourceBytes[i + 2];
Color newColor = Color.FromArgb(red, green, blue);
if (ModifyHue)
newColor = HSL.ModifyHue(newColor, Hue);
if (ModifySaturation)
newColor = HSL.ModifySaturation(newColor, Saturation);
if (ModifyLightness)
newColor = HSL.ModifyBrightness(newColor, Lightness);
destBytes[i] = newColor.B;
destBytes[i + 1] = newColor.G;
destBytes[i + 2] = newColor.R;
}
这是我的 ModifyBrightness 函数:
public static Color ModifyBrightness(Color color, double brightness)
{
HSL hsl = FromRGB(color);
hsl.L *= brightness;
return hsl.ToRGB();
}
所以基本上如果他们的亮度滑块在最中间,它的值将是 0,当我将它传递给函数时,我会将其转换为“1.0”,因此它将亮度乘以 1.0,这意味着它不会改变。如果他们将滑块一直拖到右侧,它的值将是 100,这将导致修改器为 2.0,所以我将亮度值乘以 2.0 使其翻倍。
【问题讨论】:
-
我要做的第一件事是缓存结果,并使用不安全的代码来更快地访问数组。
-
+1。使用这样的微码,阵列访问完全杀死你。每次访问都是检查最小值/最大值。请快乐不安全的指针代码。并从字节移动到同时具有所有值的结构。
-
你们有这方面的文档参考吗?当数组是指针时,Afaik 数组语法等于指针语法,不是吗?反正没有最小/最大限制。
-
@OP 如果您只需要修改 HSL,您也可以将 ImageAttributes 与 ColorMatrix 一起使用,它的执行速度将比您当前的代码快得多。
-
我对亮度、对比度、伽玛、反转和灰度滤镜使用相同的代码结构,并且使用查找表非常快。我尝试过使用指针,但实际上我注意到性能下降。数组索引不是这里的瓶颈,它是 RGB 到 HSL 的转换。正如我在问题中所说,我想使用类似于查找表的东西,但我不知道如何将其应用于 HSL,因为您无法为每个可能的双精度值创建查找表,它与 256 不同不同的字节值。