将多个单色 QImage 组合成一个彩色 QImage
Combine multiple mono QImage into a color QImage
对于颜色列表,我有相应的QImage
列表,格式为单色。单色图像经过处理,所有图像中的单个像素都可以是黑色。
我想将它们合并成彩色图像。
我有 3 个想法。
1.使用图像合成模式。我无法让它工作。 (编辑删除它,清理 post...)
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 位图像?
我不明白文档 - 这是否意味着只有 32 位图像可以 read/written 使用 scanLine()
或者无论图像类型如何,该功能都将以相同的方式工作,并且我只使用 4 个字节之一 ?
使用 32 位图像而不是 8 位或 2 位图像会更有效吗?
如果我使用 32 位图像作为目标,并尝试使用 scanLine()
写入数据,我仍然如何提高我对单色图像的读取能力?
请帮助我改进我的算法,要么改进我迭代图像所有像素的版本,要么使用一些工具,例如使用合成组合图像。
Is it actually possible to use scanLine() with 8 or 2 bit images ?
是的。
Would be more effective to use 32 bit images instead of 8 or 2 bit ?
你要衡量,具体要看具体代码。为了简单起见,我在这里使用了 8 位代码,因为您的代码确实如此。
If I use 32 bit image for destination, and try to use scanLine() to write data, still how can I improve my reading of the mono images ?
在内部循环中复制图像可能不是一个好主意
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;
}
}
}
对于颜色列表,我有相应的QImage
列表,格式为单色。单色图像经过处理,所有图像中的单个像素都可以是黑色。
我想将它们合并成彩色图像。
我有 3 个想法。
1.使用图像合成模式。我无法让它工作。 (编辑删除它,清理 post...)
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 位图像?
我不明白文档 - 这是否意味着只有 32 位图像可以 read/written 使用 scanLine()
或者无论图像类型如何,该功能都将以相同的方式工作,并且我只使用 4 个字节之一 ?
使用 32 位图像而不是 8 位或 2 位图像会更有效吗?
如果我使用 32 位图像作为目标,并尝试使用 scanLine()
写入数据,我仍然如何提高我对单色图像的读取能力?
请帮助我改进我的算法,要么改进我迭代图像所有像素的版本,要么使用一些工具,例如使用合成组合图像。
Is it actually possible to use scanLine() with 8 or 2 bit images ?
是的。
Would be more effective to use 32 bit images instead of 8 or 2 bit ?
你要衡量,具体要看具体代码。为了简单起见,我在这里使用了 8 位代码,因为您的代码确实如此。
If I use 32 bit image for destination, and try to use scanLine() to write data, still how can I improve my reading of the mono images ?
在内部循环中复制图像可能不是一个好主意
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;
}
}
}