更快的算法改变色相/饱和度/亮度位图(Faster algorithm to change Hue/

2019-07-18 06:53发布

我试图筛选位图图像来增加或减少色相,饱和度和亮度值。

我的代码工作完美,但它是缓慢的

我在内存中锁定两个位图,原始出处和当前目标。 用户可以移动各个的TrackBar控件修改每个值,然后将其转换为HSL值。 例如,在跟踪条值对应于〜1.0的范围的-1.0。

每一个事件被抛出,所述的TrackBar值改变时,我运行用于锁定目标位图,并与源位图应用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乘以亮度值加倍。

Answer 1:

我结束了研究ImageAttributes和嘉洛斯,发现性能优良。

这里是我是如何实现它的饱和度和亮度过滤器:

// Luminance vector for linear RGB
const float rwgt = 0.3086f;
const float gwgt = 0.6094f;
const float bwgt = 0.0820f;

private ImageAttributes imageAttributes = new ImageAttributes();
private ColorMatrix colorMatrix = new ColorMatrix();
private float saturation = 1.0f;
private float brightness = 1.0f;

protected override void OnPaint(object sender, PaintEventArgs e)
{
    base.OnPaint(sender, e);

    e.Graphics.DrawImage(_bitmap, BitmapRect, BitmapRect.X, BitmapRect.Y, BitmapRect.Width, BitmapRect.Height, GraphicsUnit.Pixel, imageAttributes);
}

private void saturationTrackBar_ValueChanged(object sender, EventArgs e)
{
    saturation = 1f - (saturationTrackBar.Value / 100f);

    float baseSat = 1.0f - saturation;

    colorMatrix[0, 0] = baseSat * rwgt + saturation;
    colorMatrix[0, 1] = baseSat * rwgt;
    colorMatrix[0, 2] = baseSat * rwgt;
    colorMatrix[1, 0] = baseSat * gwgt;
    colorMatrix[1, 1] = baseSat * gwgt + saturation;
    colorMatrix[1, 2] = baseSat * gwgt;
    colorMatrix[2, 0] = baseSat * bwgt;
    colorMatrix[2, 1] = baseSat * bwgt;
    colorMatrix[2, 2] = baseSat * bwgt + saturation;

    imageAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

    Invalidate();
}

private void brightnessTrackBar_ValueChanged(object sender, EventArgs e)
{
    brightness = 1f + (brightnessTrackBar.Value / 100f);

    float adjustedBrightness = brightness - 1f;

    colorMatrix[4, 0] = adjustedBrightness;
    colorMatrix[4, 1] = adjustedBrightness;
    colorMatrix[4, 2] = adjustedBrightness;

    imageAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

    Invalidate();
}


Answer 2:

你需要的应用程序配置文件你看到问题。

随机建议:

  • 使用32位每像素格式,以避免未对齐的读取。 (和读取整个32作为单一操作)
  • 避免多个RGB < - > HSL转换


文章来源: Faster algorithm to change Hue/Saturation/Lightness in a bitmap
标签: c# .net bitmap hsl