summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Christiansen <tobyase@serenityos.org>2022-01-02 21:57:44 +0100
committerIdan Horowitz <idan.horowitz@gmail.com>2022-01-04 21:41:14 +0200
commit9d45e5ac8f2dfbb4e46b1713229eef3777699fdb (patch)
treecba6dc9f266e051ceabc4a361e8ad7ad45c72f51
parentb0ab97916901fdb744adee308a9141e5109dccdb (diff)
downloadserenity-9d45e5ac8f2dfbb4e46b1713229eef3777699fdb.zip
PixelPaint: Add the FastBoxBlurFilter with configurable parameters :^)
The FastBoxBlurFilter has been living in LibGfx for a while and now it's accessible in PixelPaint. The parameters for the filter are exposed via the new Filter Gallery.
-rw-r--r--Userland/Applications/PixelPaint/CMakeLists.txt1
-rw-r--r--Userland/Applications/PixelPaint/FilterModel.cpp2
-rw-r--r--Userland/Applications/PixelPaint/Filters/FastBoxBlur.cpp74
-rw-r--r--Userland/Applications/PixelPaint/Filters/FastBoxBlur.h28
4 files changed, 105 insertions, 0 deletions
diff --git a/Userland/Applications/PixelPaint/CMakeLists.txt b/Userland/Applications/PixelPaint/CMakeLists.txt
index 20ee0bd774..92e4e6d9cb 100644
--- a/Userland/Applications/PixelPaint/CMakeLists.txt
+++ b/Userland/Applications/PixelPaint/CMakeLists.txt
@@ -20,6 +20,7 @@ set(SOURCES
Filters/BoxBlur3.cpp
Filters/BoxBlur5.cpp
Filters/Filter.cpp
+ Filters/FastBoxBlur.cpp
Filters/GaussBlur3.cpp
Filters/GaussBlur5.cpp
Filters/Grayscale.cpp
diff --git a/Userland/Applications/PixelPaint/FilterModel.cpp b/Userland/Applications/PixelPaint/FilterModel.cpp
index fef27ba6ce..f26392c661 100644
--- a/Userland/Applications/PixelPaint/FilterModel.cpp
+++ b/Userland/Applications/PixelPaint/FilterModel.cpp
@@ -9,6 +9,7 @@
#include "FilterParams.h"
#include "Filters/BoxBlur3.h"
#include "Filters/BoxBlur5.h"
+#include "Filters/FastBoxBlur.h"
#include "Filters/GaussBlur3.h"
#include "Filters/GaussBlur5.h"
#include "Filters/Grayscale.h"
@@ -29,6 +30,7 @@ FilterModel::FilterModel(ImageEditor* editor)
auto laplace_diagonal_filter = FilterInfo::create_filter<Filters::LaplaceDiagonal>(editor, edge_detect_category);
auto blur_category = FilterInfo::create_category("Blur & Sharpen", spatial_category);
+ auto fast_box_filter = FilterInfo::create_filter<Filters::FastBoxBlur>(editor, blur_category);
auto gaussian_blur_filter_3 = FilterInfo::create_filter<Filters::GaussBlur3>(editor, blur_category);
auto gaussian_blur_filter_5 = FilterInfo::create_filter<Filters::GaussBlur5>(editor, blur_category);
auto box_blur_filter_3 = FilterInfo::create_filter<Filters::BoxBlur3>(editor, blur_category);
diff --git a/Userland/Applications/PixelPaint/Filters/FastBoxBlur.cpp b/Userland/Applications/PixelPaint/Filters/FastBoxBlur.cpp
new file mode 100644
index 0000000000..9eae3fc626
--- /dev/null
+++ b/Userland/Applications/PixelPaint/Filters/FastBoxBlur.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2022, Tobias Christiansen <tobyase@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include "FastBoxBlur.h"
+#include "../FilterParams.h"
+#include <LibGUI/Label.h>
+#include <LibGUI/ValueSlider.h>
+#include <LibGfx/Filters/FastBoxBlurFilter.h>
+
+namespace PixelPaint::Filters {
+
+void FastBoxBlur::apply() const
+{
+ if (!m_editor)
+ return;
+ if (auto* layer = m_editor->active_layer()) {
+ Gfx::FastBoxBlurFilter filter(layer->bitmap());
+
+ if (m_approximate_gauss)
+ filter.apply_three_passes(m_radius);
+ else
+ filter.apply_single_pass(m_radius);
+
+ layer->did_modify_bitmap(layer->rect());
+ m_editor->did_complete_action();
+ }
+}
+
+RefPtr<GUI::Widget> FastBoxBlur::get_settings_widget()
+{
+ if (!m_settings_widget) {
+ m_settings_widget = GUI::Widget::construct();
+ m_settings_widget->set_layout<GUI::VerticalBoxLayout>();
+
+ auto& name_label = m_settings_widget->add<GUI::Label>("Fast Box Blur Filter");
+ name_label.set_font_weight(Gfx::FontWeight::Bold);
+ name_label.set_text_alignment(Gfx::TextAlignment::CenterLeft);
+ name_label.set_fixed_height(20);
+
+ auto& radius_container = m_settings_widget->add<GUI::Widget>();
+ radius_container.set_fixed_height(20);
+ radius_container.set_layout<GUI::HorizontalBoxLayout>();
+ radius_container.layout()->set_margins({ 4, 0, 4, 0 });
+
+ auto& radius_label = radius_container.add<GUI::Label>("Radius:");
+ radius_label.set_text_alignment(Gfx::TextAlignment::CenterLeft);
+ radius_label.set_fixed_size(50, 20);
+
+ auto& radius_slider = radius_container.add<GUI::ValueSlider>(Orientation::Horizontal, "px");
+ radius_slider.set_range(0, 25);
+ radius_slider.set_value(m_radius);
+ radius_slider.on_change = [&](int value) {
+ m_radius = value;
+ };
+
+ auto& gaussian_container = m_settings_widget->add<GUI::Widget>();
+ gaussian_container.set_fixed_height(20);
+ gaussian_container.set_layout<GUI::HorizontalBoxLayout>();
+ gaussian_container.layout()->set_margins({ 4, 0, 4, 0 });
+
+ auto& gaussian_checkbox = gaussian_container.add<GUI::CheckBox>("Approximate Gaussian Blur");
+ gaussian_checkbox.set_checked(m_approximate_gauss);
+ gaussian_checkbox.set_tooltip("A real gaussian blur can be approximated by running the box blur multiple times with different weights.");
+ gaussian_checkbox.on_checked = [this](bool checked) {
+ m_approximate_gauss = checked;
+ };
+ }
+
+ return m_settings_widget;
+}
+}
diff --git a/Userland/Applications/PixelPaint/Filters/FastBoxBlur.h b/Userland/Applications/PixelPaint/Filters/FastBoxBlur.h
new file mode 100644
index 0000000000..89b4cdd666
--- /dev/null
+++ b/Userland/Applications/PixelPaint/Filters/FastBoxBlur.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2022, Tobias Christiansen <tobyase@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include "Filter.h"
+
+namespace PixelPaint::Filters {
+
+class FastBoxBlur final : public Filter {
+public:
+ virtual void apply() const override;
+ virtual RefPtr<GUI::Widget> get_settings_widget() override;
+
+ virtual StringView filter_name() override { return "Fast Box Blur (& Gauss)"sv; }
+
+ FastBoxBlur(ImageEditor* editor)
+ : Filter(editor) {};
+
+private:
+ size_t m_radius { 5 };
+ bool m_approximate_gauss { false };
+};
+
+}