关于 c :Convert QImage* to void* 反之亦然

Convert QImage* to void* and vice versa

我正在开发 C QT 项目,其中包含一些模块通过一个控制器模块使用带有签名的函数相互通信:

1
notify(QString stream_id, const void* stream, unsigned __int64 size)

所以我问的是如何将 QT 数据类型主要是 QImage* 转换为 void*,反之亦然,以使用 void 指针及其大小发送数据,

我正在尝试使用此代码,但它不工作:

1
2
3
    void* imageVoidPtr = static_cast<void*>(&image);

StreamListener::getInstance()->notify(QString("Stream_Name"),imageVoidPtr,sizeof(imageVoidPtr));

------------- 编辑

我正在尝试使用以下方法检索数据:

1
2
3
4
5
    void VideoView::receive(QString stream_id, const void* stream, unsigned __int64 size){
QByteArray data = QByteArray::fromRawData(reinterpret_cast<const char*>(stream), size);
QBuffer buffer(&data);
QImageReader reader(&buffer);
QImage img = reader.read();}

-------- 编辑 2

Void* 缓冲区大小为 4 或 12(在 sizeOf(QImage) 的情况下)并且没有给出正确大小的图像字节大小的代码有什么问题,
并且接收器中接收到的图像是空的(没有出现错误)。

谢谢


令人惊讶的是,您期望它会起作用。

指针只是一个整数,它表示可以保存任意数据的内存地址。因此,无论指针指向什么,指针始终是相同大小的,因为它始终是内存地址,并且始终由固定数量的位表示,在 32 位构建中为 32,在 64 位构建中为 64。

QImage 将数据存储在堆上。实际的类只是数据的控制器。因此,无论图像有多大,sizeof() 都会为您提供相同的结果。

QImage 已经支持使用 QDataStream:

进行序列化和反序列化

1
2
3
4
5
6
7
8
9
10
11
12
  QImage img(100, 100, QImage::Format_Mono); // original image
  QByteArray data; // data container
  QBuffer buffer(&data); // io device
  buffer.open(QIODevice::ReadWrite);
  QDataStream stream(&buffer); // data stream
  stream <<img; // save img to data
  // you can now use the data.data() pointer, convert to void, and send data.size() number of bytes and put it into another byte array on the other side
  // then replicate the io dev and data stream steps too, omitted for brevity      
  QImage img2; // new image
  buffer.seek(0); // go to beginning of data
  stream >> img2; // read data into new image
  qDebug() << (img == img2) << data.size(); // true, it is the same content, size is 723 bytes, that includes the image format and raw data

使用QImage保存方法:

1
2
3
4
5
QImage image;
QByteArray ba;
QBuffer buffer(&ba);
buffer.open(QIODevice::WriteOnly);
image.save(&buffer,"PNG"); // writes image into ba in PNG format

您现在可以像这样使用 QByteArray 底层缓冲区:

1
2
void* imageVoidPtr = static_cast<void*>(ba.data());    
StreamListener::getInstance()->notify(QString("Stream_Name"), imageVoidPtr, ba.size());

如果您需要设置特定于格式的选项(例如质量,用于压缩格式),请使用 QImageWriter,而不是:

1
2
3
4
5
QByteArray ba;
QBuffer buffer(&ba);
QImageWriter writer(&buffer,"JPG");
writer.setQuality(100); //max quality for jpeg
writer.write(image);

在接收端,一切都应该很好,已经(使用 QBufferQImageReader)。


我已经为这个问题找到了一个简单的解决方案,

在将数据作为 void* 发送时,我只是将 QImage 的地址提供给通知函数,不需要大小:

1
2
 QImage image = CreateImage(imageStreamByteArray);
    StreamListener::getInstance()->notify(StreamsNames::VIDEO_DAT_IMAGE,&image,0);

在接收时我使用了这种类型的投射,但没有使用尺寸:

1
2
3
4
void VideoView::receive(QString stream_id, const void* stream, unsigned __int64 size){
    QImage *img = const_cast<QImage*>(reinterpret_cast<const QImage *>(stream));
   updateDisplay(img);
}

谢谢


乍一看,这显然是导致您的代码无法工作的问题:

1
StreamListener::getInstance()->notify(QString("Stream_Name"),imageVoidPtr,sizeof(imageVoidPtr));

最后一个参数应该是 sizeof(QImage) 而不是像下面这样:

1
StreamListener::getInstance()->notify(QString("Stream_Name"),imageVoidPtr,sizeof(QImage));

希望它以这种方式工作,但如果不是这样,最好你提一下你的代码有什么问题,如果它不工作,输出或错误是什么?