qt把html数据流转换成qimage,qt - 怎么把Ximea xiAPI相机数据转换成QImage? - 堆栈内存溢出...

这篇博客探讨了如何高效地将XI_IMG格式的数据转换为QImage,避免不必要的类型转换和低效操作。作者提供了从XI_IMG到QImage的转换函数,利用Qt的内置功能实现灰度图像处理,并考虑了不同像素格式之间的转换,包括颜色空间的调整。同时,代码中包含了错误检查和内存管理,确保了转换过程的正确性和性能。
摘要由CSDN通过智能技术生成

转换为int是不必要的,并且您以非常低效的方式进行转换; 您所需QImage::Format_Grayscale8就是使用Qt 5.5(2015年中)以来可用的QImage::Format_Grayscale8 。

无论如何,您真正想要的是一种从XI_IMG到QImage 。 默认BP_UNSAFE缓冲策略应该是充足的-在QImage会做格式转换,因此服用数据从下邳的内部缓冲区是OK。 因此,以下内容-所有转换都在Qt中实现并且非常有效-比大多数任何朴素的代码要好得多。

我没有检查某些Xi格式是否可能需要BGR交换。 如果是这样,则可以在格式选择代码中将swap设置为true ,其余的将自动发生。

static QVector grayScaleColorTable() {

static QVector table;

if (table.isEmpty()) {

table.resize(256);

auto *data = table.data();

for (int i = 0; i < table.size(); ++i)

data[i] = qRgb(i, i, i);

}

return table;

}

constexpr QImage::Format grayScaleFormat() {

return (QT_VERSION >= QT_VERSION_CHECK(5,5,0))

? QImage::Format_Grayscale8

: QImage::Format_Indexed8;

}

QImage convertToImage(const XI_IMG *src, QImage::Format f) {

Q_ASSERT(src->fmt == XI_MONO16);

Q_ASSERT((src->padding_x % 2) == 0);

if (src->fmt != XI_MONO16) return {};

const quint16 *s = static_cast(src->bp);

const int s_pad = src->padding_x/2;

if (f == QImage::Format_BGR30 ||

f == QImage::Format_A2BGR30_Premultiplied ||

f == QImage::Format_RGB30 ||

f == QImage::Format_A2RGB30_Premultiplied)

{

QImage ret{src->width, src->height, f};

Q_ASSERT((ret->bytesPerLine() % 4) == 0);

const int d_pad = ret->bytesPerLine()/4 - ret->width();

quint32 *d = (quint32*)ret.bits();

if (s_pad == d_pad) {

const int N = (src->width + s_pad) * src->height - s_pad;

for (int i = 0; i < N; ++i) {

quint32 const v = (*s++) >> (16-10);

*d++ = 0xC0000000 | v << 20 | v << 10 | v;

}

} else {

for (int j = 0; j < src->height; ++j) {

for (int i = 0; i < src->width; ++i) {

quint32 const v = (*s++) >> (16-10);

*d++ = 0xC0000000u | v << 20 | v << 10 | v;

}

s += s_pad;

d += d_pad;

}

}

return ret;

}

QImage ret{src->width, src->height, grayScaleFormat()};

const int d_pad = ret->bytesPerLine() - ret->width();

auto *d = ret.bits();

if (s_pad == d_pad) {

const int N = (src->width + s_pad) * src->height - s_pad;

for (int i = 0; i < N; ++i) {

*d++ = (*s++) >> 8;

} else {

for (int j = 0; j < src->height; ++j) {

for (int i = 0; i < src->width; ++i)

*d++ = (*s++) >> 8;

s += s_pad;

d += d_pad;

}

}

return ret;

}

QImage fromXiImg(const XI_IMG *src, QImage::Format dstFormat = QImage::Format_ARGB32Premultiplied) {

Q_ASSERT(src->width > 0 && src->height > 0 && src->padding_x >= 0 && src->bp_size > 0);

Q_ASSERT(dstFormat != QImage::Format_Invalid);

bool swap = false;

int srcPixelBytes = 0;

bool externalConvert = false;

QImage::Format srcFormat = QImage::Format_Invalid;

switch (src->fmt) {

case XI_MONO8:

srcPixelBytes = 1;

srcFormat = grayScaleFormat();

break;

case XI_MONO16:

srcPixelBytes = 2;

externalConvert = true;

break;

case XI_RGB24:

srcPixelBytes = 3;

srcFormat = QImage::Format_RGB888;

break;

case XI_RGB32:

srcPixelBytes = 4;

srcFormat = QImage::Format_RGB32;

break;

};

if (srcFormat == QImage::Format_Invalid && !externalConvert) {

qWarning("Unhandled XI_IMG image format");

return {};

}

Q_ASSERT(srcPixelBytes > 0 && srcPixelBytes <= 4);

int bytesPerLine = src->width * srcPixelBytes + src->padding_x;

if ((bytesPerLine * src->height - src->padding_x) > src->bp_size) {

qWarning("Inconsistent XI_IMG data");

return {};

}

QImage ret;

if (!externalConvert)

ret = QImage{static_cast(src->bp), src->width, src->height,

bytesPerLine, srcFormat};

else

ret = convertToImage(src, dstFormat);

if (ret.format() == QImage::Format_Indexed8)

ret.setColorTable(grayScaleColorTable());

if (ret.format() != dstFormat)

ret = std::move(ret).convertToFormat(dstFormat);

if (swap)

ret = std::move(ret).rgbSwapped();

if (!ret.isDetached()) // ensure that we don't share XI_IMG's data buffer

ret.detach();

return ret;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值