我可以在不使用光栅绘画的情况下将一个 QImage 添加到另一个吗?
Can I add one QImage to another without using raster painting ?
我的项目要求是我可以创建宽度最大为 36000 像素(高度小得多)的图像。
(图像是从 QGraphicsScene
渲染的)。
我运行进入一个限制:QPainter
限制光栅绘画的设备大小:
void QRasterPaintEnginePrivate::systemStateChanged()
{
deviceRectUnclipped = QRect(0, 0,
qMin(QT_RASTER_COORD_LIMIT, device->width()),
qMin(QT_RASTER_COORD_LIMIT, device->height()));
....
}
// This limitations comes from qgrayraster.c. Any higher and
// rasterization of shapes will produce incorrect results.
const int QT_RASTER_COORD_LIMIT = 32767;
(我尝试解决问题...)
所以...我想,我可以创建 2 个图像然后添加它们吗? (一个在彼此的尽头)
if(wOutput > 32767)
{
QImage image1 = QImage(32767, hOutput, QImage::Format_Mono);
image1.fill(QColor(Qt::white).rgb());
QRectF source(0, 0, 32767, hOutput);
QRectF target(0, 0, 32767, hOutput);
QPainter painter;
painter.begin(&image1);
outputScene->render(&painter, target, source);
painter.end();
QImage image2 = QImage(wOutput - 32767, hOutput, QImage::Format_Mono);
image2.fill(QColor(Qt::white).rgb());
source = QRectF(32767, 0, wOutput - 32767, hOutput);
target = QRectF(0, 0, wOutput - 32767, hOutput);
painter.begin(&image2);
outputScene->render(&painter, target, source);
painter.end();
// now create a combination, add image2 at the end of image1
QImage image = QImage(wOutput, hOutput, QImage::Format_Mono);
painter.begin(&image);
painter.drawImage(0, 0, image1);
painter.drawImage(32767, hOutput, image2);
painter.end();
}
else
{
// just create the image
}
看起来很合乎逻辑...但是输出没有显示 image2
。显然...我正在使用相同的光栅绘画...具有相同的限制!
还有什么其他方法可以在另一个图像的末尾添加图像? (注意 - 我的 "large" 大小是 "width" 所以我什至不认为我可以使用 scanline
来更快地复制像素)
您可以使用QImage::scanLine
获取像素数据并复制。
但是 QImage::Format_Mono
使它变得有点复杂,因为您必须考虑像素数据的对齐方式(QImage::Format_Mono
每个像素有 1 位,因此 8 个像素为一个字节)。
我建议使用可被 8 整除的宽度(例如 32760)生成第一张图片,这样您就可以复制第二张图片的行而不用移动位。
此外,颜色 table 在两个源图像中应该相同。
你可以这样做:
int w1 = 32760;
QImage image1 = QImage(w1, hOutput, QImage::Format_Mono);
//grab the first image....
//....
int w2 = wOutput - w1;
QImage image2 = QImage(w2, hOutput, QImage::Format_Mono);
//grab the second image....
//....
int bytesPerLine1 = w1 / 8; //is divisible by 8
int bytesPerLine2 = ceil(float(w2) / 8.0f); //should be right :)
QImage image = QImage(wOutput, hOutput, QImage::Format_Mono);
image.setColorTable(image1.colorTable());
for(int i = 0; i < hOutput; ++i)
{
uchar* dstSL = image.scanLine(i);
uchar* src1SL = image1.scanLine(i);
memcpy(dstSL, src1SL, bytesPerLine1);
uchar* src2SL = image2.scanLine(i);
memcpy(&dstSL[bytesPerLine1], src2SL, bytesPerLine2);
}
我还建议阅读 QImage 文档:Pixel Manipulation and QImage::Format
我的项目要求是我可以创建宽度最大为 36000 像素(高度小得多)的图像。
(图像是从 QGraphicsScene
渲染的)。
我运行进入一个限制:QPainter
限制光栅绘画的设备大小:
void QRasterPaintEnginePrivate::systemStateChanged()
{
deviceRectUnclipped = QRect(0, 0,
qMin(QT_RASTER_COORD_LIMIT, device->width()),
qMin(QT_RASTER_COORD_LIMIT, device->height()));
....
}
// This limitations comes from qgrayraster.c. Any higher and
// rasterization of shapes will produce incorrect results.
const int QT_RASTER_COORD_LIMIT = 32767;
(我尝试解决问题...
所以...我想,我可以创建 2 个图像然后添加它们吗? (一个在彼此的尽头)
if(wOutput > 32767)
{
QImage image1 = QImage(32767, hOutput, QImage::Format_Mono);
image1.fill(QColor(Qt::white).rgb());
QRectF source(0, 0, 32767, hOutput);
QRectF target(0, 0, 32767, hOutput);
QPainter painter;
painter.begin(&image1);
outputScene->render(&painter, target, source);
painter.end();
QImage image2 = QImage(wOutput - 32767, hOutput, QImage::Format_Mono);
image2.fill(QColor(Qt::white).rgb());
source = QRectF(32767, 0, wOutput - 32767, hOutput);
target = QRectF(0, 0, wOutput - 32767, hOutput);
painter.begin(&image2);
outputScene->render(&painter, target, source);
painter.end();
// now create a combination, add image2 at the end of image1
QImage image = QImage(wOutput, hOutput, QImage::Format_Mono);
painter.begin(&image);
painter.drawImage(0, 0, image1);
painter.drawImage(32767, hOutput, image2);
painter.end();
}
else
{
// just create the image
}
看起来很合乎逻辑...但是输出没有显示 image2
。显然...我正在使用相同的光栅绘画...具有相同的限制!
还有什么其他方法可以在另一个图像的末尾添加图像? (注意 - 我的 "large" 大小是 "width" 所以我什至不认为我可以使用 scanline
来更快地复制像素)
您可以使用QImage::scanLine
获取像素数据并复制。
但是 QImage::Format_Mono
使它变得有点复杂,因为您必须考虑像素数据的对齐方式(QImage::Format_Mono
每个像素有 1 位,因此 8 个像素为一个字节)。
我建议使用可被 8 整除的宽度(例如 32760)生成第一张图片,这样您就可以复制第二张图片的行而不用移动位。
此外,颜色 table 在两个源图像中应该相同。
你可以这样做:
int w1 = 32760;
QImage image1 = QImage(w1, hOutput, QImage::Format_Mono);
//grab the first image....
//....
int w2 = wOutput - w1;
QImage image2 = QImage(w2, hOutput, QImage::Format_Mono);
//grab the second image....
//....
int bytesPerLine1 = w1 / 8; //is divisible by 8
int bytesPerLine2 = ceil(float(w2) / 8.0f); //should be right :)
QImage image = QImage(wOutput, hOutput, QImage::Format_Mono);
image.setColorTable(image1.colorTable());
for(int i = 0; i < hOutput; ++i)
{
uchar* dstSL = image.scanLine(i);
uchar* src1SL = image1.scanLine(i);
memcpy(dstSL, src1SL, bytesPerLine1);
uchar* src2SL = image2.scanLine(i);
memcpy(&dstSL[bytesPerLine1], src2SL, bytesPerLine2);
}
我还建议阅读 QImage 文档:Pixel Manipulation and QImage::Format