diff --git a/src/tools/pixelate/pixelatetool.cpp b/src/tools/pixelate/pixelatetool.cpp index 9b430a2d..45fa6a64 100644 --- a/src/tools/pixelate/pixelatetool.cpp +++ b/src/tools/pixelate/pixelatetool.cpp @@ -17,6 +17,7 @@ #include "pixelatetool.h" #include +#include #include #include #include @@ -57,90 +58,45 @@ PixelateTool::copy(QObject* parent) return new PixelateTool(parent); } -void -write_block(QImage& image, - int x_start, - int y_start, - int pixel_size, - QRgb block_color) -{ - assert(x_start + pixel_size < image.width()); - assert(y_start + pixel_size < image.height()); - - for (auto x = x_start; x < x_start + pixel_size; x++) { - for (auto y = y_start; y < y_start + pixel_size; y++) { - image.setPixel(x, y, block_color); - } - } -} - -QRgb -calculate_block_averge(QImage& image, int x_start, int y_start, int pixel_size) -{ - assert(x_start + pixel_size < image.width()); - assert(y_start + pixel_size < image.height()); - - int red_count = 0; - int blue_count = 0; - int green_count = 0; - int pixel_count = 0; - for (auto x = x_start; x < x_start + pixel_size; x++) { - for (auto y = y_start; y < y_start + pixel_size; y++) { - auto pixel = image.pixel(x, y); - - red_count += qRed(pixel); - green_count += qGreen(pixel); - blue_count += qBlue(pixel); - pixel_count++; - } - } - return (qRgb(red_count / pixel_count, - green_count / pixel_count, - blue_count / pixel_count)); -} void PixelateTool::process(QPainter& painter, const QPixmap& pixmap, bool recordUndo) { + if (recordUndo) { updateBackup(pixmap); } + QPoint& p0 = m_points.first; QPoint& p1 = m_points.second; - auto pixelRatio = pixmap.devicePixelRatio(); - QRect selection = QRect(p0, p1).normalized(); - QRect selectionScaled = QRect(p0 * pixelRatio, p1 * pixelRatio).normalized(); - QPixmap* source = new QPixmap(pixmap.copy(selectionScaled)); + // If thickness is less than 1, use old blur process + if (m_thickness <= 1) { + auto pixelRatio = pixmap.devicePixelRatio(); - QImage original_image{ source->toImage() }; - QImage imageResult{ source->toImage() }; - unsigned int pixel_size = m_thickness; - if (pixel_size < 1) { - pixel_size = 1; + QRect selectionScaled = + QRect(p0 * pixelRatio, p1 * pixelRatio).normalized(); + + QGraphicsBlurEffect* blur = new QGraphicsBlurEffect; + blur->setBlurRadius(10); + QGraphicsPixmapItem* item = + new QGraphicsPixmapItem(pixmap.copy(selectionScaled)); + item->setGraphicsEffect(blur); + + QGraphicsScene scene; + scene.addItem(item); + + scene.render(&painter, selection, QRectF()); + blur->setBlurRadius(12); + scene.render(&painter, selection, QRectF()); + } else { + int width = selection.width() * (0.5 / qMax(1, m_thickness)); + + QPixmap t = pixmap.copy(selection); + t = t.scaledToWidth(qMax(width, 10), Qt::SmoothTransformation); + t = t.scaledToWidth(selection.width()); + painter.drawImage(selection, t.toImage()); } - - const unsigned int width = source->width(); - const unsigned int height = source->height(); - - // Don't start pixelating until the region is at least as big as the pixel - if ((width > pixel_size) && (height > pixel_size)) { - for (unsigned int x = 0; x < (width - pixel_size); x += pixel_size) { - for (unsigned int y = 0; y < (height - pixel_size); y += pixel_size) { - auto block_color = - calculate_block_averge(original_image, x, y, pixel_size); - write_block(imageResult, x, y, pixel_size, block_color); - } - } - } - QPixmap result{ QPixmap::fromImage(imageResult) }; - - QGraphicsScene scene; - scene.addPixmap(result); - - scene.render(&painter, selection, QRectF()); - - delete source; } void