简体   繁体   中英

Convert QImage* to void* and vice versa

I am working on C++ QT project which contains some modules communicating to each other through one controller module using a function with signature :

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

So I am asking about how to convert a QT Data Type mainly QImage* to void* , and vice versa, to send the data using the void pointer and its size,

i am trying to work with this code, but it`s not working:

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

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

------------- Edit

And i am trying to retrieve the data using :

    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();}

-------- Edit 2

What`s wrong with the code that the size of the Void* buffer is 4 or 12 (in case of sizeOf(QImage) ) and not giving the right size of the Image Bytes size, and the received image in the receiver is empty (No errors appears).

Thanks

It is amazing that you expect this to work.

A pointer is just an integer number, that represents a memory address that may hold arbitrary data. Thus the pointer is always the same size, regardless of what it points to, because it is always a memory address, and it is always represented by a fixed number of bits, 32 in a 32bit build and 64 in a 64bit build.

QImage stores the data on the heap. The actual class is just a controller for the data. Therefore sizeof() will give you the same result regardless of how big the image is.

QImage already supports serialization and deserialization using QDataStream :

  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

Use QImage save method :

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

You can now use the QByteArray underlying buffer like this:

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

If you need to set format-specific options (eg quality, for compressed formats), use a QImageWriter , instead:

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

On the receiving end, everything should be fine, already (using a QBuffer and a QImageReader ).

At the first sight, this is the issue that apparently has caused your code not to work:

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

The last argument should be sizeof(QImage) instead like follows:

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

Hope it works this way, but if not, it's much better if you mention what is wrong with your code, if it's not working what is the output or error?

I have found a simple solution for this question,

As while sending the data as a void* i have just give the function the address of the QImage to the notify function, and no need for the size:

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

And while in receiving i have use this type of casting, without using the size:

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

Thanks

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM