[Qt] QLabel schlechtes Antialiasing

Hunter

Erfahrenes Mitglied
Hallo.

Mein Problem besteht darin, dass der Text ein schlechtes Antialiasing besitzt (siehe Anhang). Nun, mittels googeln hab ich leider auch nichts herausgefunden.
Nun, wie kann ich ein besseres Antialiasing erreichen?
C++:
QFont font("SegoeUI",32);
font.setStyleStrategy(QFont::PreferAntialias);
title->setFont(font);
 

Anhänge

  • bad.png
    bad.png
    7,6 KB · Aufrufe: 20
Ja eben, Antialiasing wird ja benutzt, aber eben nicht so gut. Siehe Anhang, so möchte ich es gerne haben.
 

Anhänge

  • good.png
    good.png
    2,9 KB · Aufrufe: 22
Hallo Hunter,
Nun, mittels googeln hab ich leider auch nichts herausgefunden.
Naja, ich hab auch mal gegoogelt, hier sind die ersten beiden Treffer:
http://stackoverflow.com/questions/6746276/how-to-enable-anti-aliasing-on-qlabel
http://qt-project.org/forums/viewthread/24665

Bei stackoverflow wurde dieser Schnipsel als Lösung vorgeschlagen:
C++:
QLabel * l = new QLabel();
QFont f=l->font();
f.setStyleStrategy(QFont::PreferAntialias);
l->setFont(f);
Bzw. falls du gleich die Fonts aller Labels der Application ändern willst:
C++:
QFont f=QApplication::font();
f.setStyleStrategy(QFont::PreferAntialias);
QApplication::setFont(f);
In der Regel sollte allerdings das Antialiasing standardmäßig aktiviert sein. Es besteht jedoch eine geringe Chance, dass dein Qt es nicht aktiviert hat. Im Qt-Forum (2. Link) wird deshalb vorgeschlagen das mit dem Hilfsprogramm "qconfig" herauszufinden.
Vielleicht lässt sich ja aber auch einfach diese bestimmte Schriftart nicht so weich zeichnen wie andere? Hast du das Ganze vielleicht schon mal mit Arial oder Calibri ausprobiert? Wird es dadurch besser?
Ist es sehr wichtig, dass es dieser Font ist und er weich sein sollte? Im Notfall könnte man ihn ja künstlich weicher zeichnen...

Gruß Technipion
 
Antialiasing ist ja aktiviert, nur ist es halt nicht das beste Antialiasing.
Ja, es ist bei jedem Font dieses Antialiasing.
 
Hallo Hunter,
ich hatte vorhin kurz Zeit und hab deshalb etwas mit dem Antialiasing herumgespielt. Es scheint wirklich so, als würden manche Schriftarten einfach schlechter dargestellt als andere...

Zum Vergleich habe ich schnell ein einfaches MainWindow-Projekt im QtCreator angelegt und im Hauptfenster zwei Labels anzeigen lassen, das obere mit und das untere ohne Antialiasing. Ich hab' dir einen Screenshot davon angehängt, auch wenn du das ja schon kennst ;).

Falls du jetzt aber wirklich "schöneres" Antialiasing brauchst dachte ich mir, man könnte ja einfach einen Gauß-Filter auf den Text anwenden (ihn also weichzeichnen). Ich habe daraufhin ein bisschen gegoogelt und bin bei Stackoverflow fündig geworden:
http://stackoverflow.com/questions/3903223/qt4-how-to-blur-qpixmap-image

Dort habe ich den Algorithmus her, der den Gauß-Filter auf ein QImage anwendet (war zu faul ihn selbst zu schreiben :D).

Ich habe dann einfach schnell etwas Code ******* - ich meine natürlich zusammengeschustert o_O.
Das kam dabei heraus (ist nur die mainwindow.cpp, aber wie gesagt, es ist das Standard-Projekt):
C++:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QLabel>
#include <QVBoxLayout>



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;
}

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QWidget *centralWindow = new QWidget;
    QLabel *upperLabel = new QLabel("Sample Text.");
    QLabel *lowerLabel = new QLabel("Sample Text.");
    QFont upperFont = QFont("SegoeUI", 32);
    QFont lowerFont = QFont("SegoeUI", 32);
    //lowerFont.setStyleStrategy(QFont::NoAntialias); // you may comment out this line for better results
    upperLabel->setFont(upperFont);
    lowerLabel->setFont(lowerFont);
    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addWidget(upperLabel);
    mainLayout->addWidget(lowerLabel);
    centralWindow->setLayout(mainLayout);
    centralWindow->show();
    this->setCentralWidget(centralWindow);

    // try rendering the text to a QPixmap and apply antialiasing to it
    QPixmap pixmap = lowerLabel->grab();
    QImage image = pixmap.toImage();
    image = blurred(image, image.rect(), 1, false);
    lowerLabel->setPixmap(QPixmap::fromImage(image));
}

MainWindow::~MainWindow()
{
    delete ui;
}
Es sieht natürlich etwas gewöhnungsbedürftig aus, für alle Interessierten habe ich auch hiervon Screenshots angehängt. Einmal habe ich ein Label mit und einmal ein Label ohne Antialiasing weichgezeichnet. Den Radius sollte man übrigens nicht zu groß wählen, sonst sieht es schon sehr krass aus :p.

Keine Ahnung ob dir das weiterhilft Hunter...
Gruß Technipion

Antialiasing vs Blur (mit vorherigem Antialiasing).png Antialiasing vs Blur (ohne vorheriges Antialiasing).png Vergleich Antialiasing (mit vs ohne).png Antialiasing vs Blur (Radius zu groß gewählt).png
 
An sich keine schlechte Idee, aber leider kann ich nicht mit Pixmaps arbeiten, da auch Links drinnen sind.

Wenn ich jedoch mit Pixmaps arbeiten könnte, würde ich den Text einfach Skalieren, dann ergibt sich ja ein gutes Antialiasing.
Leider funktioniert "scaledContents" bei Texte nicht...
 
Zurück