Qt超大像素图绘制技术方案

问题描述
最近因有个工业控制项目的需要,有一幅65000X18000的bmp图需要去绘制;但是按照目前Qt 提供的类QPixmap 或者 QImage,都没有办法直接完成这项工作的。通过阅读Qt源码我们发现,Qt支持绘制的最大区域为32767X 32767;

为了突破Qt这个限制,解决这个技术瓶颈问题,我们设计出一种切片思想解决方案,具体如下:

1、对一幅超大的图片进行切片,使其范围在 32767 X 32767 范围内。
2、绘制工作在切片上操作执行
3、把绘制好的切片图像再重新写会原始超大图中,完美实现大图绘制工作。

示例代码如下

QImage image(65000,18000,QImage::Format_Mono);
1、获取切片区域
QRect rcSlice(100,1000,40000,10000);
QImage imageSlice = image.copy(rcSlice)
2、绘制操作
QPainter painter(&imageSlice);
….
….
3、切换写回原始大图中
int x = 0;
int y = 0;
int w = m_rcLastCpy.width();
int h = m_rcLastCpy.height();
int pixels_to_copy = w;
int lines_to_copy = h;
bool byteAligned = !(pixels_to_copy & 7);
if (byteAligned)
{
const uchar *src = image.bits();
uchar *dest = m_pImage->bits() + ((m_rcLastCpy.x() * m_pImage->depth()) >> 3) + m_rcLastCpy.y() * m_pImage->depth()*m_pImage->bytesPerLine();
const int bytes_to_copy = (pixels_to_copy * image.depth()) >> 3;
for (int i = 0; i < lines_to_copy; ++i) { memcpy(dest, src, bytes_to_copy); src += image.bytesPerLine(); dest += m_pImage->bytesPerLine();
}
}
else
{
const uchar *src = image.bits();
uchar *dest = m_pImage->bits() + m_rcLastCpy.y() * m_pImage->bytesPerLine();
for (int i = 0; i < lines_to_copy; ++i) {
for (int j = 0; j < pixels_to_copy; ++j) { if (src[(x + j) >> 3] & (0x80 >> ((x + j) & 7)))
dest[(j) >> 3] |= (0x80 >> ((j) & 7));
else
dest[(j) >> 3] &= ~(0x80 >> ((j) & 7));
}
src += image.bytesPerLine();
dest += m_pImage->bytesPerLine();
}
}

至此,完美的解决了超大图绘制的工作。