2017-10-08 11 views
1

J'ai une image png 4 canaux avec 8x8 pixels qui est chargée par un QImage. Le QImage est ensuite mis à l'échelle par un facteur de 200, de sorte que l'image aura une nouvelle résolution de 1600x1600, chaque pixel d'origine ayant une taille de 200x200. Mais quand cette image est ajoutée à un par le biais d'un QPixmap et affichée à l'écran, les pixels dessinés auront des tailles légèrement différentes.Comment garantir une taille de pixel uniforme lors de la mise en peinture de QImage?

J'ai pris des captures d'écran avec Gimp et j'ai regardé l'image peinte de plus près. Il semble que chaque pixel soit légèrement plus grand qu'il ne devrait l'être, 201 au lieu de 200 pixels de large par exemple. Le tout dernier pixel d'une ligne sera alors plus petit pour compenser, de sorte que toute l'image aura la taille correcte à la fin.

Cela ne se produit pas pour tous les facteurs d'échelle, 100 est très bien par exemple, et sont donc des facteurs qui sont une puissance de 2, tels que 256.

Mon approche originale utilisait un QGraphicsView et un QGraphicsPixmapItem auquel cas J'ai mis à l'échelle le GraphicsItem à la place de l'image. L'effet était le même.

Quel effet est-ce que je vois ici? Et quoi, si quelque chose, peut être fait à ce sujet?

Le code pour reproduire ce problème est très simple

int scale = 200; 
image = QImage("some image file"); 
QPixmap pixmap = QPixmap::fromImage(image.scaled(image.size() * scale)); 
some_label->setPixmap(pixmap); 
+1

Je ne suis pas sûr que cela résout votre problème, mais vous pourriez faire la mise à l'échelle vous-même en dessinant le pixmap (non mis à l'échelle), comme on le voit ici: https://github.com/gerbilvis/gerbil/blob/master/gui/ widgets/scaledview.cpp # L103 La mise à l'échelle se fait via un QTransform mis en place ici: https://github.com/gerbilvis/gerbil/blob/master/gui/widgets/scaledview.cpp#L72 (votre QTransform est beaucoup plus simple à configurer en haut, avec échelle fixe et traduction) Btw. C'est une méthode très efficace avec le backend de rendu GL. – ypnos

+0

Merci. Je n'aurais jamais deviné que ce problème pourrait provenir de l'algorithme de mise à l'échelle. Je pensais que c'était un simple problème de peinture/présentation. Mais je viens de sauvegarder l'image mise à l'échelle sur le disque et bien sûr, c'est faux aussi. Merci pour le conseil :) – ifschleife

Répondre

0

Transforme la solution la plus simple à mon problème est d'utiliser QOpenGLWidget dans le QGraphicsView:

setViewport(new QOpenGLWidget); 

Cette ligne unique dans le constructeur sera résulte en une précision beaucoup plus élevée lors de la mise à l'échelle d'une image avec l'avertissement d'ajouter OpenGL en tant que dépendance. Un autre gotcha avec cette approche est que l'appel setViewport invalide la plupart des paramètres effectués sur un QGraphicsView. Donc, si la vue est définie dans un fichier d'interface utilisateur, comme dans mon cas, assurez-vous d'appeler d'autres setters après en appelant setViewport.

Je ne pouvais pas trouver une meilleure solution qui fonctionnerait sans OpenGL, à court d'écrire mon propre rasterizer bien sûr.