Angesichts einer .png
Bild mit einem transparenten Hintergrund, ich möchte die Bounding Box der nicht transparenten Daten zu finden. Die Verwendung von verschachtelten for
Loops mit QImage.pixel()
ist schmerzhaft langsam. Gibt es eine eingebaute Methode, dies in Qt zu tun?Hat Qt eine Möglichkeit, die Begrenzungsbox eines Bildes zu finden?
Antwort
Wenn Pixel() für Sie zu langsam ist, sollten Sie mehr effiziente reihenweise Daten adressing, ein QImage p gegeben:
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;
}
}
ich bezweifle es schneller als das bekommen.
Es gibt eine Option, die die Verwendung einer QGraphicsPixmapItem
und die Abfrage der Begrenzungsbox des undurchsichtigen Bereichs (QGraphicsPixmapItem::opaqueArea().boundingRect()
) umfasst. Nicht sicher, ob es der beste Weg ist, aber es funktioniert :) Es könnte sich lohnen, in Qt's Quellcode zu gucken, um zu sehen, welcher Code das Herzstück ist.
Der folgende Code wird die Breite und Höhe des Bildes durch die Breite und Höhe der undurchsichtigen Teile des Bildes gefolgt ausdrucken:
QPixmap p("image.png");
QGraphicsPixmapItem *item = new QGraphicsPixmapItem(p);
std::cout << item->boundingRect().width() << "," << item->boundingRect().height() << std::endl;
std::cout << item->opaqueArea().boundingRect().width() << "," << item->opaqueArea().boundingRect().height() << std::endl;
OpaqueArea() erstellt einen ganzen Pfad, der den Bereich beschreibt. Das sollte langsamer sein als die Berechnung eines einfachen Begrenzungsrechtecks. – ypnos
Hoffentlich kann das OP einige Timing-Ergebnisse veröffentlichen. Es würde mich interessieren, wie viel Zeit beide Optionen benötigen. Aber ja, für komplizierte Bilder kann ich mir nur vorstellen, dass es langsamer ist. –
Ich habe ein paar grobe Zeiten meiner Gesamtaufgabe gemacht, ohne einen Mikro-Benchmark zu erstellen. Dieser Ansatz verwendete im Wesentlichen die gleiche Wanduhrzeit wie meine verschachtelten for-Schleifen, benötigte aber weniger CPU-Zeit. – retracile
- 1. Java: Schnellste Möglichkeit, die Helligkeit eines Bildes zu ändern
- 2. Wie wird eine Vorschau eines Bildes in qt angezeigt?
- 3. Gibt es eine Möglichkeit, die Größe/Breite eines Bildes in einer UIImageView mit AspectFit Set zu finden?
- 4. Hat Qt eine C-Schnittstelle?
- 5. Abrufen der Begrenzungsbox eines Geodjango-Multipolygon-Objekts
- 6. Gibt es eine Möglichkeit zu vermeiden, die Alt eines Bildes anzuzeigen, während eckig geladen wird?
- 7. Bildposition innerhalb eines größeren Bildes finden
- 8. Gibt es eine Möglichkeit, die Größe eines Arrays zu erhalten, ohne es manuell zu finden?
- 9. Wie kann ich die dominante Farbe eines Bildes finden?
- 10. So finden Sie die aktuelle Position eines Bildes. (Sprite Kit)
- 11. Qt machen ein qmainwindow mit videowidget innerhalb eines Bildes
- 12. Effektive Möglichkeit, eine Datei zu finden Codierung
- 13. Einstellen eines Bildes auf einem Etikett in Qt
- 14. Hinzufügen eines Bildes zu UITabBar
- 15. Um die Ecken eines Bildes runden
- 16. keine Möglichkeit, die Verbindung des Bildes zu öffnen
- 17. Begrenzungsbox vs. Rechteck
- 18. Wie erhöht man die Schärfe eines Bildes?
- 19. Gibt es eine Möglichkeit, die Entfernung eines Elements von einem anderen in jQuery zu finden?
- 20. Gibt es eine Möglichkeit, die Kardinalität (Größe) eines Enums in C++ zu finden?
- 21. Gibt es eine Möglichkeit, die "naturalWidth" eines Bildes mit jquery auszulesen?
- 22. die Auflösung eines Bildes im ImageNet-Datensatz
- 23. gibt es eine Möglichkeit, Qt-Creator + Boost Library zu kombinieren?
- 24. iOS: Looping über die Pixel eines Bildes
- 25. Finden von Randpixeln eines Bildes mit transparenter Umgebung (zur Kolisionserkennung)
- 26. Gibt es eine Möglichkeit, MP3s in Qt 4.5 zu spielen?
- 27. schwenken zu einem bestimmten Teil eines Bildes
- 28. Hat Qt 4.5 Skins?
- 29. Gibt es eine Möglichkeit, die Ausführung eines Prozesses zu verzögern?
- 30. Gibt es eine Möglichkeit, die Textfeldinformationen eines Containers zu erhalten?
+1: Nizza. Ich wollte gerade die Option scanLine() betrachten. –
Es ist nicht wie Qt-Docs es gut werben. Nahm mich ein halbes Jahr, um es herauszufinden. – ypnos
Ich habe ein paar grobe Zeiten meiner Gesamtaufgabe gemacht, ohne einen Mikro-Benchmark zu erstellen. Dieser Ansatz verwendete im Wesentlichen die gleiche Menge an CPU-Zeit wie Arnolds Lösung, reduzierte jedoch die Wanduhrzeit. – retracile