Pārlūkot izejas kodu

PixelPaint: Add grayscale filter
Add a new Color category to the Filter menu. Add the Grayscale
filter under Filter->Color to turn the selected layer to grey colors.
Created GrayscaleFilter.h. Modify Filter.h to allow filters
without parameters.

savary1 3 gadi atpakaļ
vecāks
revīzija
dd912bd351

+ 1 - 0
Userland/Applications/PixelPaint/FilterParams.h

@@ -16,6 +16,7 @@
 #include <LibGUI/TextBox.h>
 #include <LibGfx/Filters/BoxBlurFilter.h>
 #include <LibGfx/Filters/GenericConvolutionFilter.h>
+#include <LibGfx/Filters/GrayscaleFilter.h>
 #include <LibGfx/Filters/LaplacianFilter.h>
 #include <LibGfx/Filters/SharpenFilter.h>
 #include <LibGfx/Filters/SpatialGaussianBlurFilter.h>

+ 12 - 0
Userland/Applications/PixelPaint/main.cpp

@@ -660,6 +660,18 @@ int main(int argc, char** argv)
         }
     }));
 
+    auto& color_filters_menu = filter_menu.add_submenu("&Color");
+    color_filters_menu.add_action(GUI::Action::create("Grayscale", [&](auto&) {
+        auto* editor = current_image_editor();
+        if (!editor)
+            return;
+        if (auto* layer = editor->active_layer()) {
+            Gfx::GrayscaleFilter filter;
+            filter.apply(layer->bitmap(), layer->rect(), layer->bitmap(), layer->rect());
+            editor->did_complete_action();
+        }
+    }));
+
     auto& help_menu = window->add_menu("&Help");
     help_menu.add_action(GUI::CommonActions::make_about_action("Pixel Paint", app_icon, window));
 

+ 2 - 1
Userland/Libraries/LibGfx/Filters/Filter.h

@@ -23,7 +23,8 @@ public:
 
     virtual const char* class_name() const = 0;
 
-    virtual void apply(Bitmap&, const IntRect&, const Bitmap&, const IntRect&, const Parameters&) = 0;
+    virtual void apply(Bitmap&, IntRect const&, Bitmap const&, IntRect const&, Parameters const&) {};
+    virtual void apply(Bitmap&, IntRect const&, Bitmap const&, IntRect const&) {};
 
 protected:
     Filter() { }

+ 45 - 0
Userland/Libraries/LibGfx/Filters/GrayscaleFilter.h

@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2021, David Savary <david.savarymartinez@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <LibGfx/Filters/Filter.h>
+
+namespace Gfx {
+
+class GrayscaleFilter : public Filter {
+public:
+    GrayscaleFilter() { }
+    virtual ~GrayscaleFilter() { }
+
+    virtual char const* class_name() const override { return "GrayscaleFilter"; }
+
+    virtual void apply(Bitmap& target_bitmap, IntRect const& target_rect, Bitmap const& source_bitmap, IntRect const& source_rect) override
+    {
+        // source_rect should be describing the pixels that can be accessed
+        // to apply this filter, while target_rect should describe the area
+        // where to apply the filter on.
+        VERIFY(source_rect.size() == target_rect.size());
+        VERIFY(target_bitmap.rect().contains(target_rect));
+        VERIFY(source_bitmap.rect().contains(source_rect));
+
+        for (auto y = 0; y < source_rect.height(); ++y) {
+            ssize_t source_y = y + source_rect.y();
+            ssize_t target_y = y + target_rect.y();
+            for (auto x = 0; x < source_rect.width(); ++x) {
+                ssize_t source_x = x + source_rect.x();
+                ssize_t target_x = x + target_rect.x();
+
+                auto source_pixel = source_bitmap.get_pixel(source_x, source_y);
+                auto target_color = source_pixel.to_grayscale();
+
+                target_bitmap.set_pixel(target_x, target_y, target_color);
+            }
+        }
+    }
+};
+
+}