mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +00:00
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:
parent
78bc856e07
commit
97f66562cc
Notes:
sideshowbarker
2024-07-17 08:37:36 +09:00
Author: https://github.com/MacDue Commit: https://github.com/SerenityOS/serenity/commit/97f66562cc Pull-request: https://github.com/SerenityOS/serenity/pull/15463 Reviewed-by: https://github.com/AtkinsSJ ✅ Reviewed-by: https://github.com/awesomekling
2 changed files with 53 additions and 35 deletions
|
@ -6,17 +6,14 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <AK/Math.h>
|
#include <LibGfx/Filters/MatrixFilter.h>
|
||||||
#include <LibGfx/Filters/ColorFilter.h>
|
|
||||||
#include <LibGfx/Matrix3x3.h>
|
|
||||||
|
|
||||||
namespace Gfx {
|
namespace Gfx {
|
||||||
|
|
||||||
class HueRotateFilter : public ColorFilter {
|
class HueRotateFilter : public MatrixFilter {
|
||||||
public:
|
public:
|
||||||
HueRotateFilter(float angle_degrees)
|
HueRotateFilter(float angle_degrees)
|
||||||
: ColorFilter(angle_degrees)
|
: MatrixFilter(calculate_hue_rotate_matrix(angle_degrees))
|
||||||
, m_operation(calculate_operation_matrix(angle_degrees))
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,37 +22,12 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
float angle_degrees() const
|
|
||||||
{
|
|
||||||
return m_amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual StringView class_name() const override { return "HueRotateFilter"sv; }
|
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:
|
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 cos_angle = 0;
|
||||||
float sin_angle = 0;
|
float sin_angle = 0;
|
||||||
AK::sincos(angle_rads, sin_angle, cos_angle);
|
AK::sincos(angle_rads, sin_angle, cos_angle);
|
||||||
|
@ -77,8 +49,6 @@ private:
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
}
|
}
|
||||||
|
|
||||||
FloatMatrix3x3 m_operation;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
48
Userland/Libraries/LibGfx/Filters/MatrixFilter.h
Normal file
48
Userland/Libraries/LibGfx/Filters/MatrixFilter.h
Normal 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;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue