Есть ли функция для получения ограничивающей рамки небелой области QImage?

У меня есть QImage, и мне нужно обрезать окружающий белый цвет (т.е. обрезать его только до небелой области).

Есть ли в QImage или QPixmap встроенная функция, которая возвращает ограничивающую рамку небелой области изображения, аналогичную QGraphicsPixmapItem::opaqueArea()? Это означает, что за пределами этой ограничивающей рамки нет небелых пикселей.


person sashoalm    schedule 04.01.2013    source источник


Ответы (2)


Я не вижу встроенной функции для этого, но ее должно быть достаточно легко сделать самостоятельно:

QRect getBoundsWithoutColor(QImage qImage, const Qcolor &exclusionColor = Qt:white)
{
    QRect ofTheKing;

    int maxX = 0; int minX = qImage.width;
    int maxY = 0; int minY = qImage.height;

    for(int x=0; x < qImage.width(); x++)
        for(int y=0; y < qImage.height(); y++)
            if (QColor.fromRgb(qImage.pixel(x, y)) != exclusionColor)
            {
                if(x < minX) minX = x;
                if(x > maxX) maxX = x;
                if(y < minY) minY = y;
                if(y > maxY) maxY = y;
            }

    if (minX > maxX || minY > maxY)
        // The whole picture is white. How you wanna handle this case is up to you.
    else
        ofTheKing.setCoords(minX, minY, maxX+1, maxY+1);

    return ofTheKing;
 }
person Foggzie    schedule 04.01.2013

В QImage нет встроенной такой функции, но, поскольку QImage обеспечивает прямой доступ к данным пикселей, кодировать самостоятельно не должно быть слишком сложно. На моей голове это, вероятно, выглядело бы примерно так.

const QRgb CROP_COLOR = QColor(Qt::white).rgb();

QImage crop(const QImage& image)
{
    QRect croppedRegion(0, 0, image.width(), image.height());

    // Top
    for (int row = 0; row < image.height(); row++) {
        for (int col = 0; col < image.width(); col++) {
            if (image.pixel(col, row) != CROP_COLOR) {
                croppedRegion.setTop(row);
                row = image.height();
                break;
            }
        }
    }

    // Bottom
    for (int row = image.height() - 1; row >= 0; row--) {
        for (int col = 0; col < image.width(); col++) {
            if (image.pixel(col, row) != CROP_COLOR) {
                croppedRegion.setBottom(row);
                row = -1;
                break;
            }
        }
    }

    // Left
    for (int col = 0; col < image.width(); col++) {
        for (int row = 0; row < image.height(); row++) {
            if (image.pixel(col, row) != CROP_COLOR) {
                croppedRegion.setLeft(col);
                col = image.width();
                break;
            }
        }
    }

    // Right
    for (int col = image.width(); col >= 0; col--) {
        for (int row = 0; row < image.height(); row++) {
            if (image.pixel(col, row) != CROP_COLOR) {
                croppedRegion.setRight(col);
                col = -1;
                break;
            }
        }
    }

    return image.copy(croppedRegion);
}

Отказ от ответственности: этот код, вероятно, можно оптимизировать. Я не тестировал его, похоже, он компилируется, но где-то может быть опечатка. Я просто поместил его туда, чтобы показать общую идею.

person Fred    schedule 04.01.2013