Étant donné une image .png code> avec un arrière-plan transparent, je veux trouver la zone de sélection des données non transparentes. Utilisation de pour code> boucles avec qimage.pixel () code> est douloureusement lent. Y a-t-il une méthode intégrée de faire cela dans qt? P>
3 Réponses :
Il existe une option qui consiste à utiliser un Le code suivant imprimera la largeur et la hauteur de l'image suivie. Par la largeur et la hauteur des parties opaques de l'image: p> qgraphicspixmapitem code> et interrogation pour la zone de liaison de la zone opaque ( qgraphicspixmapitem :: opaquearea (). BoundingRect () code>). Je ne sais pas si c'est le meilleur moyen mais ça marche :) Il peut être utile de creuser dans le code source de QT pour voir quel code est au cœur de celui-ci.
Opadeaaa () construit un chemin entier décrivant la zone. Cela devrait être plus lent que le calcul de rectangle de liaison simple.
Espérons que l'OP peut poster des résultats de synchronisation. Je serais intéressé de voir combien de temps prendre les deux options. Mais oui, pour des images compliquées, je ne peux que l'imaginer que cela soit plus lent.
J'ai fait quelques timbres difficiles de ma tâche sur-toutes tâche sans créer de micro-repère. Cette approche utilisait essentiellement la même quantité de temps d'horloge murale que mes boucles imbriquées, mais a pris moins de temps de processeur.
Merci pour les commentaires et félicitations pour votre nouveau pouvoir de vote :)
Je viens de tomber sur QgraphicspixMapitem à nouveau et j'ai pensé que c'était vraiment sympa que vous l'avez dirigé ici. En outre, si l'on a besoin du trajet d'un QIMAGE ou de QPIXMAP, ils ne trouvent pas facilement que Qt fournit la fonctionnalité de QGraphicsPixMapitem.
Si pixel () est trop lent pour vous, envisagez une adressage de données de ligne plus efficace, étant donné un QIMAGE:
int l =p.width(), r = 0, t = p.height(), b = 0;
for (int y = 0; y < p.height(); ++y) {
QRgb *row = (QRgb*)p.scanLine(y);
bool rowFilled = false;
for (int x = 0; x < p.width(); ++x) {
if (qAlpha(row[x])) {
rowFilled = true;
r = std::max(r, x);
if (l > x) {
l = x;
x = r; // shortcut to only search for new right bound from here
}
}
}
if (rowFilled) {
t = std::min(t, y);
b = y;
}
}
Ce n'est pas comme si les documents Qt le font la publicité. M'a pris une demi-année pour en savoir plus.
J'ai fait quelques timbres difficiles de ma tâche sur-toutes tâche sans créer de micro-repère. Cette approche utilisait essentiellement la même quantité de CPU-Time que la solution d'Arnold, mais une période de temps murale réduite.
La solution la plus facile et relativement rapide est de faire comme suit: si vous avez un dans ce cas, un Vous pouvez également essayer qpixmap code> plutôt que qimage code>, Ensuite, vous pouvez utiliser: p> qpixmap :: créemaskfromcolor code> convertira la pixmap en une image et faites la même chose que ci-dessus. Une solution encore plus courte pour qpixmap code> est la suivante: p> qpixmap code> sans canal alpha entraînera un Région vide, vous devrez peut-être vérifier explicitement cela. Incidemment, c'est aussi ce que qgraphicspixmapitem :: opaquearea code> mentionné par @ARNOLD Spence est basé sur. P> qimage :: créatealphamask code> , bien que le point de coupure ne soit pas à 0 alpha mais plutôt quelque part à une demi-opacité. p> p>