将多个单声道QImage组合成颜色QImage

时间:2016-01-19 18:34:22

标签: qt qimage

对于颜色列表,我有一个相应的QImage列表,格式为mono。单色图像的处理方式使得单个像素可以是所有图像中的黑色。

我想将它们合并为彩色图像。

我有3个想法。

1。使用图像合成模式。我无法让它工作。 (编辑删除它,清理帖子......)

2。当添加到目的地时,将单色图像用作每种颜色的遮罩。
我不知道如何实现它。

3。迭代像素 - 慢,文档说像素处理函数很慢......

这有效:

// Creating destination image
// m_colors: list of (n+1) QCcolor (last one corresponding to background)
// m_images: list of n QImage, Format_Mono, all of the same size (as the destination)
// using indexed image for destination since I have a limited palette
QImage preview = QImage(rect.size().toSize(), QImage::Format_Indexed8);
int previewWidth  = preview.size().width();
int previewHeight = preview.size().height();
int colorsSize = m_colors.size();
for(int k = 0; k < colorsSize; ++k)
{
    preview.setColor(k, m_colors.at(k).rgb());
}
--colorsSize;

// combining images
for(int j = 0; j < previewHeight; ++j)
{
    for(int i = 0; i < previewWidth; ++i)
    {
        // set background color
        preview.setPixel(i, j, colorsSize);
        for(int k = 0; k < colorsSize; ++k)
        {
            QImage im = m_images.at(k);
            if(!im.isNull())
            {
                if(m_images.at(k).pixelIndex(i, j) == 0)
                {
                    preview.setPixel(i, j, k);
                }
            }
        }
    }
}

我至少应该使用scanLine()进行改进,但不知道如何...我只能找到使用scanLine()和32位图像的示例,而不是8或2。
实际上是否可以将scanLine()与8位或2位图像一起使用?

我不明白文档 - 它是否意味着只能使用scanLine()读取/写入32位图像,或者无论图像类型如何,该函数都将以相同的方式工作,我只使用一个4个字节?
使用32位图像而不是8位或2位更有效吗?

如果我将32位图像用于目的地,并尝试使用scanLine()来写入数据,那么如何才能提高单声道图像的读取效果呢?

请帮我改进算法,要么改进我在迭代图像的所有像素上工作的版本,要么使用一些工具,比如使用合成图像组合图像。

1 个答案:

答案 0 :(得分:1)

  

实际上是否可以将scanLine()与8位或2位图像一起使用?

是的。

  

使用32位图像而不是8位或2位更有效吗?

您必须进行衡量,具体取决于具体代码。为简单起见,我在这里使用了8位代码,因为你的代码确实如此。

  

如果我使用32位图像作为目的地,并尝试使用scanLine()来写入数据,那么如何才能提高单声道图像的读取效果呢?

在内循环中复制图像可能不是一个好主意

QImage im = m_images.at(k)

然后不要将该副本用于下次访问。

if(m_images.at(k).pixelIndex(i, j) == 0)

如果内部循环遍历图像而不是迭代内部循环中的目标像素,它应该加快绘画速度。

如果图像是单色的,则扫描线将指向需要解压缩的打包颜色信息。让convertToFormat转换图像然后使用scanLine读取解压缩的信息更容易(也许更快)。在下面的示例中,图像都是8位。

#include<vector>

#include <QtGui/QImage>
#include <QtGui/QColor>

static char * img1[] = { 
   "5 5 2 1", "a c #000000", "b c #ffffff",
   "aabba", "aabba", "aabba", "aabba", "aabba"
};

static char * img2[] = {
   "5 5 2 1","a c #000000","b c #ffffff",
   "aaaaa", "aaaaa", "bbbbb", "bbbbb", "aaaaa"
};

int main( int argc, char* arg[] )
{
   auto images = std::vector<QImage>( 2 );
   images[0] = QImage( img1 );
   images[1] = QImage( img2 );

   auto colors = std::vector<QColor>( 2 );
   colors[0] = QColor( Qt::red );
   colors[1] = QColor( Qt::green );

   QImage combined = QImage( images[0].size(), QImage::Format_Indexed8 );
   combined.setColor( 0, Qt::black );
   combined.fill(0);

   for( int k = 1, num = images.size(); k <= num; ++k )
   {
      combined.setColor( k, colors[k-1].rgb() );
      QImage img= images[k-1];

      for( int i = 0, height = img.height(); i < height ; ++i )
      {
         uchar* src = img.scanLine(i);
         uchar* dst = combined.scanLine(i);

         for( int j = 0, width = mono.width(); j < width; ++j )
         {
            if( src[j] != 0 ) 
               dst[j] = k;
         }
      }
   }