From 4bad4dc8d5cbca8d5ce44413105d110609a6b17a Mon Sep 17 00:00:00 2001 From: Tim Ledbetter Date: Thu, 19 Jan 2023 17:52:10 +0000 Subject: [PATCH] PixelPaint: Use background color when cropping layer to content This commit expands the functionality of the "Crop Image to Content" and "Crop Layer to Content" features by allowing them to detect and crop the background color of an image instead of just cropping transparent pixels. The background color is determined by looking at the corner pixels of the image. If no background color is found, the old behavior of cropping transparent pixels is retained. --- Userland/Applications/PixelPaint/Layer.cpp | 38 ++++++++++++++++++++-- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/Userland/Applications/PixelPaint/Layer.cpp b/Userland/Applications/PixelPaint/Layer.cpp index cb318f8f98..e7535bff92 100644 --- a/Userland/Applications/PixelPaint/Layer.cpp +++ b/Userland/Applications/PixelPaint/Layer.cpp @@ -335,16 +335,48 @@ void Layer::set_edit_mode(Layer::EditMode mode) Optional Layer::nonempty_content_bounding_rect() const { + auto determine_background_color = [](NonnullRefPtr const& bitmap) -> Optional { + auto bitmap_size = bitmap->size(); + auto top_left_pixel = bitmap->get_pixel(0, 0); + auto top_right_pixel = bitmap->get_pixel(bitmap_size.width() - 1, 0); + auto bottom_left_pixel = bitmap->get_pixel(0, bitmap_size.height() - 1); + auto bottom_right_pixel = bitmap->get_pixel(bitmap_size.width() - 1, bitmap_size.height() - 1); + + if (top_left_pixel == top_right_pixel || top_left_pixel == bottom_left_pixel) + return top_left_pixel; + + if (bottom_right_pixel == bottom_left_pixel || bottom_right_pixel == top_right_pixel) + return top_right_pixel; + + return {}; + }; + + enum class ShrinkMode { + Alpha, + BackgroundColor + }; + Optional min_content_y; Optional min_content_x; Optional max_content_y; Optional max_content_x; - + auto background_color = determine_background_color(m_content_bitmap); + auto shrink_mode = background_color.has_value() ? ShrinkMode::BackgroundColor : ShrinkMode::Alpha; for (int y = 0; y < m_content_bitmap->height(); ++y) { for (int x = 0; x < m_content_bitmap->width(); ++x) { auto color = m_content_bitmap->get_pixel(x, y); - if (color.alpha() == 0) - continue; + switch (shrink_mode) { + case ShrinkMode::BackgroundColor: + if (color == background_color) + continue; + break; + case ShrinkMode::Alpha: + if (color.alpha() == 0) + continue; + break; + default: + VERIFY_NOT_REACHED(); + } min_content_x = min(min_content_x.value_or(x), x); min_content_y = min(min_content_y.value_or(y), y); max_content_x = max(max_content_x.value_or(x), x);