QT4 ¿Cómo desenfocar la imagen de QPixmap?QT4 ¿Cómo desenfocar la imagen de QPixmap?
Busco algo así como uno de los siguientes:
Blur(pixmap);
painter.Blur();
painter.Blur(rect);
¿Cuál es la mejor manera de hacer esto?
QT4 ¿Cómo desenfocar la imagen de QPixmap?QT4 ¿Cómo desenfocar la imagen de QPixmap?
Busco algo así como uno de los siguientes:
Blur(pixmap);
painter.Blur();
painter.Blur(rect);
¿Cuál es la mejor manera de hacer esto?
A Gaussian blur es una forma simple de crear un efecto de desenfoque.
Edit: Y lo, me encontré con Qt's QGraphicsBlurEffect. Presentado en Qt 4.6, parece hacer exactamente lo que quieres.
No tengo idea de cómo aplicar QGraphicsBlurEffect a pixmap ... – Astronavigator
Los QGraphicsEffects están destinados a ser aplicados a vistas de gráficos, no pixmaps.Sin embargo, la idea general de un borrón guassiano es el camino a seguir; solo tendrá que implementar el algoritmo usted mismo en el mapa de píxeles. (Sin embargo, podría ser más rápido/más fácil de convertir a una QImage). –
Todo el mundo conoce estos algoritmos. Pero para implementarlos, tengo que encontrar la forma de: 1. convertir QPixmap en 2d array 2. forma de convertir de 2d array a pixmap. Si su consejo es implementarlo yo mismo, entonces explique cómo convertir entre QPixmap y 2d array – Astronavigator
Salida esto:
#include <QtGui/QApplication>
#include <QImage>
#include <QPixmap>
#include <QLabel>
QImage blurred(const QImage& image, const QRect& rect, int radius, bool alphaOnly = false)
{
int tab[] = { 14, 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 };
int alpha = (radius < 1) ? 16 : (radius > 17) ? 1 : tab[radius-1];
QImage result = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
int r1 = rect.top();
int r2 = rect.bottom();
int c1 = rect.left();
int c2 = rect.right();
int bpl = result.bytesPerLine();
int rgba[4];
unsigned char* p;
int i1 = 0;
int i2 = 3;
if (alphaOnly)
i1 = i2 = (QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3);
for (int col = c1; col <= c2; col++) {
p = result.scanLine(r1) + col * 4;
for (int i = i1; i <= i2; i++)
rgba[i] = p[i] << 4;
p += bpl;
for (int j = r1; j < r2; j++, p += bpl)
for (int i = i1; i <= i2; i++)
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha/16) >> 4;
}
for (int row = r1; row <= r2; row++) {
p = result.scanLine(row) + c1 * 4;
for (int i = i1; i <= i2; i++)
rgba[i] = p[i] << 4;
p += 4;
for (int j = c1; j < c2; j++, p += 4)
for (int i = i1; i <= i2; i++)
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha/16) >> 4;
}
for (int col = c1; col <= c2; col++) {
p = result.scanLine(r2) + col * 4;
for (int i = i1; i <= i2; i++)
rgba[i] = p[i] << 4;
p -= bpl;
for (int j = r1; j < r2; j++, p -= bpl)
for (int i = i1; i <= i2; i++)
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha/16) >> 4;
}
for (int row = r1; row <= r2; row++) {
p = result.scanLine(row) + c2 * 4;
for (int i = i1; i <= i2; i++)
rgba[i] = p[i] << 4;
p -= 4;
for (int j = c1; j < c2; j++, p -= 4)
for (int i = i1; i <= i2; i++)
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha/16) >> 4;
}
return result;
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QLabel label;
QImage image("image.png");
image = blurred(image,image.rect(),10,false);
label.setPixmap(QPixmap::fromImage(image));
label.show();
return a.exec();
}
Método 1a: agarrar los trozos crudos y hágalo usted mismo. Tendrá que estar lo suficientemente familiarizado con mapas de bits y algoritmos borrosos para implementar el desenfoque usted mismo. Si quiere ese tipo de precisión, este es el camino a seguir.
QImage image = pixmap.toImage();
if (image.format() != QImage::Format_RGB32)
image = image.convertToFormat(QImage::Format_RGB32);
uchar* bits = image.bits();
int rowBytes = image.bytesPerLine();
DoMyOwnBlurAlgorithm(bits, image.width(), image.height(), rowBytes);
return QPixmap::fromImage(image);
Método 1b: who needs raw bits? Puede usar image.pixel (x, y) y image.setPixel (x, y, color) en su lugar. Esto no será tan rápido como 1a, pero debería ser un poco más fácil de entender y codificar.
QImage image = pixmap.toImage();
QImage output(image.width(), image.height(), image.format());
for (int y=0; y<image.height(); ++y)
for (int x=0; x<image.width(); ++x)
output.setPixel(getBlurredColor(image, x, y));
return output;
Método 2: utilice un QGraphicsBlurEffect, a través de un widget o escena. El código aquí usa un widget de etiqueta:
QPixmap BlurAPixmap(const QPixmap& inPixmap)
{
QLabel* label = new QLabel();
label->setPixmap(inPixmap);
label->setGraphicsEffect(new QGraphicsBlurEffect());
QPixmap output(inPixmap.width(), inPixmap.height());
QPainter painter(&output);
label->render(&painter);
return output;
}
Modifique según sea necesario. Por ejemplo, supongo que el efecto de desenfoque de gráficos predeterminado es aceptable. Estoy usando el Método 2 en mi proyecto.
1º) Declarar la rutina externa QT:
QT_BEGIN_NAMESPACE
extern Q_WIDGETS_EXPORT void qt_blurImage(QPainter *p, QImage &blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0);
QT_END_NAMESPACE
segundo) Uso:
extern QImage srcImg;//source image
QPixmap pxDst(srcImg.size());//blurred destination
pxDst.fill(Qt::transparent);
{
QPainter painter(&pxDst);
qt_blurImage(&painter, srcImg, 2, true, false);//blur radius: 2px
}
A veces me pregunto por qué se han planteado preguntas de menor calidad en lugar de las buenas. La suya es hasta ahora la mejor respuesta a esta pregunta. +1 – mhcuervo
Vamos a contribuir a este tema. A partir de Qt 5.3, siguiente función le ayudará mucho con la aplicación de QGraphicsEffect a QImage (y no perder la alfa)
QImage applyEffectToImage(QImage src, QGraphicsEffect *effect, int extent = 0)
{
if(src.isNull()) return QImage(); //No need to do anything else!
if(!effect) return src; //No need to do anything else!
QGraphicsScene scene;
QGraphicsPixmapItem item;
item.setPixmap(QPixmap::fromImage(src));
item.setGraphicsEffect(effect);
scene.addItem(&item);
QImage res(src.size()+QSize(extent*2, extent*2), QImage::Format_ARGB32);
res.fill(Qt::transparent);
QPainter ptr(&res);
scene.render(&ptr, QRectF(), QRectF(-extent, -extent, src.width()+extent*2, src.height()+extent*2));
return res;
}
ellos, utilizando esta función para difuminar su imagen es sencillo:
QGraphicsBlurEffect *blur = new QGraphicsBlurEffect;
blur->setBlurRadius(8);
QImage source("://img1.png");
QImage result = applyEffectToImage(source, blur);
result.save("final.png");
Por supuesto, no es necesario guardarlo, esto fue solo un ejemplo de utilidad. incluso Usted puede dejar una sombra:
QGraphicsDropShadowEffect *e = new QGraphicsDropShadowEffect;
e->setColor(QColor(40,40,40,245));
e->setOffset(0,10);
e->setBlurRadius(50);
QImage p("://img3.png");
QImage res = applyEffectToImage(p, e, 40);
Y tenga en cuenta el parámetro de medida, se añade extent
número de píxeles a todos los lados de la imagen original, especialmente útiles para las sombras y difumina para que no se corte.
Creo que liuyanghejerry ha esperado el tiempo suficiente para obtener la mejor respuesta. –