2010-09-15 65 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