2010-09-15 84 views

回答

4

如果像素()是用於你太慢,考慮更多高效的逐行數據adressing,給定一個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; 
    } 
} 

我懷疑它會得到任何比這更快。

+0

+1:很好。我正要看看scanLine()選項。 – 2010-09-15 22:01:54

+0

這不像是Qt文檔正在做廣告。花了我半年的時間來了解它。 – ypnos 2010-09-15 22:05:19

+1

我在沒有創建微基準的情況下完成了我的全部任務的一些粗略計時。這種方法基本上使用了與Arnold解決方案相同的CPU時間量,但減少了掛鐘時間。 – retracile 2010-09-15 23:33:18

3

有一個選項涉及使用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; 
+0

opaqueArea()構造一個描述該區域的完整路徑。這應該比簡單的邊界矩形計算慢。 – ypnos 2010-09-15 21:43:59

+0

希望OP可以發佈一些計時結果。我有興趣瞭解兩種選擇需要多少時間。但是,對於複雜的圖像,我只能想象它會變慢。 – 2010-09-15 21:51:33

+0

我在沒有創建微基準的情況下對我的全部任務做了一些粗略的計時。這種方法與我的嵌套for循環基本上使用相同數量的掛鐘時間,但花費更少的CPU時間。 – retracile 2010-09-15 23:31:47