Bildqualität nach Aufruf von QPixmap->scaled()

Alles rund um die Programmierung mit Qt
Antworten
jasper
Beiträge: 60
Registriert: 3. Februar 2009 11:36
Wohnort: Hamburg

Bildqualität nach Aufruf von QPixmap->scaled()

Beitrag von jasper »

Hallo Forum,
ich möchte ein Widget drucken, welches ein Balkendiagramm enthält.
1. Im ersten Schritt lade ich das Widget in QPixmap:
MyPixmap = QPixmap::grapWidget(pMyWidget);
2. Nun skaliere ich das Image passend für den Ausdruck herunter:
MyPixmap = MyPixmap->scaled(intWidth, intHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation)
3. Anschließend übergebe ich das Image an QImage:
MyImage = MyPixmap->toImage();
4. Nun speichere ich das Image als Datei
MyImage->save(strFileName)
5. Abschließend geht's ab zum Drucker

Mein Problem:
Ohne Skalierung ist das Bild gestochen scharf, nach der Skalierung
ist das Bild ziemlich verschmiert, egal ob *.png, *.bmp oder *.jpg.
Meine Frage:
Wie kann ich das Image ohne Verlust der Bildqualität verkleinern?
Oder gibt es eine geschicktere Möglichkeit?
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Dir gehts doch nur darum, das Widget zu drucken, oder?
Warum dann diesen "Affentanz"?

QWidget hat doch ein schönes

Code: Alles auswählen

void QWidget::render ( QPaintDevice * target, const QPoint & targetOffset = QPoint(), const QRegion & sourceRegion = QRegion(), RenderFlags renderFlags = RenderFlags( DrawWindowBackground | DrawChildren ) )
Ein QPrinter IST ein QPaintDevice.
Bastel dir also einen QPrinter zusammen, übergeb ihn an QWidget::render(), und alles ist gut.

So kannst du im übrigen auch ganz einfach ein Pixmap in der richtigen Größe - ohne rumskalieren - erstellen, denn ein QPixmap ist - na ? - ein QPaintDevice ;)

Grüße
Franz
jasper
Beiträge: 60
Registriert: 3. Februar 2009 11:36
Wohnort: Hamburg

Bildqualität nach Aufruf von QPixmap->scaled()

Beitrag von jasper »

Hallo Franz,
erst einmal Danke für deinen Hinweis auf QWidget::render().
So richtig komme ich aber immer noch nicht weiter. Ich versuche
das mal zu erklären:
Die Druckvorschau von meinem Balkendiagramm beinhaltet einem
Rahmen, Logo, Überschrift und noch ein paar andere Daten.
Daher möchte ich das eigentliche Balkendiagramm, welches ich auf
einem Widget gezeichnet habe, als Bild in die Druckvorschau einbinden.
Dazu muss ich das gesamte Bild verkleinern. Dazu sind mir bisher
zwei Varianten bekannt:
1. QPixmap->scaled():
Das Ergebnis ist verschmiert
2. QWidget->render(QPixmap):
Das Ergebnis in QPixmap enthält nur einen Ausschnitt des Widgets

Mache ich irgend etwas falsch oder befinde ich mich generell auf dem Holzweg?

Gruß

Jasper
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Re: Bildqualität nach Aufruf von QPixmap->scaled()

Beitrag von franzf »

jasper hat geschrieben:1. QPixmap->scaled():
Das Ergebnis ist verschmiert
QPixmap::scaled() hat noch mehr Parameter ;)
(Tip: setze transformMode auf Qt::SmoothTransformation)
2. QWidget->render(QPixmap):
Das Ergebnis in QPixmap enthält nur einen Ausschnitt des Widgets
Da würde mich dein Code interessieren. Denn eigentlich sollte das ganze Widget korrekt in das Pixmap gerendert werden, vorausgesetzt das Pixmap ist groß genug, und die zusätzlichen render()-Parameter (die du eigentlich weglassen solltest) passen.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Re: Bildqualität nach Aufruf von QPixmap->scaled()

Beitrag von franzf »

jasper hat geschrieben:Die Druckvorschau von meinem Balkendiagramm beinhaltet einem
Rahmen, Logo, Überschrift und noch ein paar andere Daten.
Daher möchte ich das eigentliche Balkendiagramm, welches ich auf
einem Widget gezeichnet habe, als Bild in die Druckvorschau einbinden.
Auch dazu noch schnell:
Ein Widget ist (na was? ;)) auch ein QPaintDevice.
Von demher ist sowas in der ARt möglich:

Code: Alles auswählen

widget1->render(widget2);
wenn du jetzt dem render() noch ein paar passende Argumente mitgibst (welcher Ausschnitt von widget1 in welchen Ausschnitt von widget2 gerendert werden soll), kannst du dein previewWidget füllen und dieses auf selbem Wege auch auf einen QPrinter zeichnen.
jasper
Beiträge: 60
Registriert: 3. Februar 2009 11:36
Wohnort: Hamburg

Beitrag von jasper »

Hallo Frantz,
ich habe das Problem mit dem skalieren von Bildern als Ganzes
nicht lösen können. Alle Ansätze, in denen das ganze Bild verkleinert
wird, haben eine Verschmierung des Bildes zur Folge.

Die Vektorisierung eines Bildes ist mir für "mal eben" zu kompliziert. Daher habe ich mir mit einem Screenshot beholfen. Dies ist in der QT-Beispielanwendung imageviewer gut umgesetzt. Eigenartigerweise funktioniert die dortige Vorgehensweise nur mit einem QPrinter,
welcher dann ein gestochen scharfes Bild/Ergebnis liefert. Verwendet
man dort als QPaintDevice ein QPixmap, so ist das Ergebnis wiederum
verschmiert.

Gruß

Jasper
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

jasper hat geschrieben:Die Vektorisierung eines Bildes ist mir für "mal eben" zu kompliziert.

Code: Alles auswählen

QSvgGenerator gen;
gen.setFileName( fileName );
gen.setSize( QSize( (int)_scene->width(), (int)_scene->height() ) );
        
QPainter pnt;
pnt.begin( &gen );
_scene->render( &pnt );
pnt.end();
QSvgGenerator gibts seit Qt-4.3.

Grüße
Franz
Antworten