reworked pixelate to simplier method provided by @kpcee and used old blur effect when pixelate kernel < 1

This commit is contained in:
Jeremy Borgman
2020-09-14 14:57:25 -05:00
committed by borgmanJeremy
parent ab65c22db2
commit 460e30c2ce

View File

@@ -17,6 +17,7 @@
#include "pixelatetool.h"
#include <QApplication>
#include <QGraphicsBlurEffect>
#include <QGraphicsPixmapItem>
#include <QGraphicsScene>
#include <QImage>
@@ -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