Есть ли в Qt способ найти ограничительную рамку изображения? - PullRequest
8 голосов
/ 15 сентября 2010

Учитывая .png изображение с прозрачным фоном, я хочу найти ограничивающую рамку непрозрачных данных. Использование вложенных циклов for с QImage.pixel() мучительно медленно. Есть ли встроенный способ сделать это в Qt?

Ответы [ 2 ]

4 голосов
/ 16 сентября 2010

Если pixel () слишком медленный для вас, рассмотрите более эффективную построчную адресацию данных, учитывая QImage p:

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

Я сомневаюсь, что это будет быстрее, чем это.

4 голосов
/ 16 сентября 2010

Существует один вариант, который включает использование QGraphicsPixmapItem и запрос ограничительной рамки непрозрачной области (QGraphicsPixmapItem::opaqueArea().boundingRect()). Не уверен, что это лучший способ, но он работает :) Возможно, стоит покопаться в исходном коде Qt, чтобы увидеть, какой код лежит в основе.

Следующий код распечатает ширину и высоту изображения, а затем ширину и высоту непрозрачных частей изображения:

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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...