reworked pixelate to simplier method provided by @kpcee and used old blur effect when pixelate kernel < 1
This commit is contained in:
committed by
borgmanJeremy
parent
ab65c22db2
commit
460e30c2ce
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user