LibGfx: Add MatrixFilter and convert HueRotateFilter to be one

This moves the apply a matrix operation to each [r,g,b] vector in an
image to a general class.
This commit is contained in:
MacDue 2022-10-03 20:41:31 +01:00 committed by Sam Atkins
parent 78bc856e07
commit 97f66562cc
Notes: sideshowbarker 2024-07-17 08:37:36 +09:00
2 changed files with 53 additions and 35 deletions

View file

@ -6,17 +6,14 @@
#pragma once
#include <AK/Math.h>
#include <LibGfx/Filters/ColorFilter.h>
#include <LibGfx/Matrix3x3.h>
#include <LibGfx/Filters/MatrixFilter.h>
namespace Gfx {
class HueRotateFilter : public ColorFilter {
class HueRotateFilter : public MatrixFilter {
public:
HueRotateFilter(float angle_degrees)
: ColorFilter(angle_degrees)
, m_operation(calculate_operation_matrix(angle_degrees))
: MatrixFilter(calculate_hue_rotate_matrix(angle_degrees))
{
}
@ -25,37 +22,12 @@ public:
return true;
}
float angle_degrees() const
{
return m_amount;
}
virtual StringView class_name() const override { return "HueRotateFilter"sv; }
protected:
Color convert_color(Color original) override
{
FloatVector3 rgb = {
original.red() / 256.0f,
original.green() / 256.0f,
original.blue() / 256.0f,
};
rgb = m_operation * rgb;
auto safe_float_to_u8 = [](float value) -> u8 {
return static_cast<u8>(AK::clamp(value, 0.0f, 1.0f) * 256);
};
return Color {
safe_float_to_u8(rgb[0]),
safe_float_to_u8(rgb[1]),
safe_float_to_u8(rgb[2]),
original.alpha()
};
}
private:
static FloatMatrix3x3 calculate_operation_matrix(float angle)
static FloatMatrix3x3 calculate_hue_rotate_matrix(float angle_degrees)
{
float angle_rads = angle * (AK::Pi<float> / 180);
float angle_rads = angle_degrees * (AK::Pi<float> / 180);
float cos_angle = 0;
float sin_angle = 0;
AK::sincos(angle_rads, sin_angle, cos_angle);
@ -77,8 +49,6 @@ private:
};
// clang-format on
}
FloatMatrix3x3 m_operation;
};
}

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2022, MacDue <macdue@dueutil.tech>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Math.h>
#include <LibGfx/Filters/ColorFilter.h>
#include <LibGfx/Matrix3x3.h>
namespace Gfx {
class MatrixFilter : public ColorFilter {
public:
MatrixFilter(FloatMatrix3x3 operation, float amount = 1.0f)
: ColorFilter(amount)
, m_operation(operation)
{
}
protected:
Color convert_color(Color original) override
{
auto constexpr u8_max = AK::NumericLimits<u8>::max();
auto safe_float_to_u8 = [](float value) -> u8 {
return AK::clamp(static_cast<int>(value * u8_max), 0, u8_max);
};
FloatVector3 rgb = {
original.red() / float(u8_max),
original.green() / float(u8_max),
original.blue() / float(u8_max),
};
rgb = m_operation * rgb;
return Color {
safe_float_to_u8(rgb[0]),
safe_float_to_u8(rgb[1]),
safe_float_to_u8(rgb[2]),
original.alpha()
};
}
private:
FloatMatrix3x3 const m_operation;
};
}