How to convert QImage to QByteArray? - c++

I am trying to create QByteArray from QImage, however although I tried lots of varient, I couldn't handle it.
What I am doing is :
QImage img_enrll; // <--- There is an image coming from another function.
QByteArray arr((char*)img_enrll.bits(),img_enrll.byteCount()); // <-- convertion but I am not sure it is true or not.
funcCheck((unsigned char*)arr.data(), arr.size(), 0, &sam, 1, &n);
virtual Error funcCheck (const uint8_t src[],
size_t src_len,
size_t tout_ms,
IRawSample* dst[],
size_t dst_len,
size_t* dst_n )
However Error code is return Invalid Data. I think that converting QImage to QByteArray is wrong. Please could you kindly help me how to convert to QByteArray?

You could do this:
QImage img_enrll;
QByteArray arr;
QBuffer buffer(&arr);
buffer.open(QIODevice::WriteOnly);
img_enrll.save(&buffer, "yourformat");
Having written that, if you need this for serialization, you are better of with QDataStream.

Try this:
QByteArray arr = QByteArray::fromRawData((const char*)img.bits(), img.byteCount());

In my case I needed a deep copy, so what worked was:
QByteArray arr(img.byteCount(), Qt::Uninitialized) // or resize if it already exists
memcpy(arr.data(), img.constBits(), img.byteCount());

Related

Read Access Violation. _Mem was nullptr while assigning QString after calling HeapAlloc()

I have a program that is using HeapAlloc() to allocate a struct that contains a QString and a few QByteArray structs.
Struct code:
struct Environment {
QString internalLinksDomain;
QByteArray aboutTelegram;
QByteArray aboutContacts;
QByteArray aboutFrequent;
QByteArray aboutSessions;
QByteArray aboutWebSessions;
QByteArray aboutChats;
QByteArray aboutLeftChats;
};
My code:
Environment* e = (Environment*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(Environment));
e->internalLinksDomain = "Test data";
I have also tried..
e->internalLinksDomain.append("Test data");
Both send me to the atomic file in Visual Studio. I have attached a screen shot of the error and its position in the function causing the error.
VS Error

Write and read from memory using: avio_alloc_context

My overall goal is to capture the desktop screen and encapsulate in a webm container with encoding such as VP8 or VP9. I can save it as a file, but my intention is to stream the video to a webbrowser and using mediasource extension to view the content.
Now am stuck att writing/reading the data of memory using avio_alloc_context .
avio_alloc_context(ioBuffer, IOBUFSIZE, 1, nullptr, readFromBuffer, writeToBuffer, nullptr);
Does anyone have code snippets for both read and write functions?
From this question i found the write function:
std::vector<uint8_t> outputData;
int mediaMuxCallback(void *opaque, uint8_t *buf, int bufSize)
{
outputData.insert(outputData.end(), buf, buf + bufSize);
return bufSize;
}
How should the read function be implemented any idea?
Is a vector the best alternative or how about an IStream which one is easier?

Qt "tcpserver->write(string)"

i have a very simple question here, How can i send a string with
tcpserver->write(string);
I tried:
tcpserver->write("string")
and it works, but if i want to input a string in there, i get a "no matching function to call to 'QtcpSocket::write(QString)'"
error,
so i tried converting the string to "data" and then send it, but i got a ton of errors...
And my question is: How can i easly send a string thru my tcpserver?
(I should also mention, that i am very new to programming)
You need to convert string to QByteArray, for example:
tcpserver->write(string.toLocal8Bit());
tcpserver->write(string.toUtf8());
Try tcpserver->write((const char *)string.data(), string.length()*sizeof(QChar));
QTcpSocket has 3 overloads for write () function
qint64 write (const char *data);
qint64 write (const char *data, qint64 len);
qint64 write (const QByteArray &data);
So Convert QString to any of them. Just try
tcpserver->write (string.toLatin1 ());

sending struct via Qt UDP

I am trying to setup two way communication via the QUdpSocket. I am trying to send a struct consisting of a C++ Eigenvector and a double. I have tried serializing into a QByteArray as follows:
MyStruct toSend;
QByteArray buf;
QDataStream s(&buf, QIODevice::WriteOnly);
if (false) s.setByteOrder(QDataStream::LittleEndian);
std::string vec_str = eigenToStr(toSend.vec);
s << (double)toSend.test1 << QString(vec_str.c_str());
Where eigenToStr() converts the Eigenvector to a string.
However, I am unable to read the message on the other end. When I convert back to a string before sending the QByteArray, I get #ffffff. So I assume it's an issue with the QByteArray/QDataStream conversion.
I would appreciate any suggestions as to how I might serialize my struct so that I can send it via UDP.
Thanks!
QByteArray and QDataStream cooperate very well:). If you really want write the raw data to QDataStream , please use the method :
int QDataStream::writeRawData(const char * s, int len)
And personally I prefer to overload << way to write user data to QDataStream, such as
QDataStream& operator <<(QDataStream& out,MyStruct & data)
Then probably code looks as :
MyStruct toSend;
QByteArray buf;
QDataStream s(&buf, QIODevice::WriteOnly);
if (false) s.setByteOrder(QDataStream::LittleEndian);//false ?
s << toSend;

Qt + protobuf, types?

I would like to dip into Google's protocol buffers in Qt development, but I am having trouble figuring out how to incorporate them best.
Ultimately, I want to send with QUdpSocket and QTcpSocket using protocol buffers.
What is the best method for going between a protocol buffer message to sending the data over a socket (QByteArray) and then back again at the other side?
Creating a QByteArray from a protobuf object:
Person person; // a protobuf object
person.set_id(123);
person.set_name("Bob");
person.set_email("bob#example.com");
std::ostringstream out;
person.SerializeToOstream(&out);
QByteArray byteArray(out.str().c_str());
sendSerializedPersonOverQTcpSocket(byteArray);
Reading back a protobuf object from a QByteArray:
QByteArray byteArray = readSerializedPersonFromQTcpSocket();
Person person;
if (!person.ParseFromArray(byteArray, byteArray.size())) {
std::cerr << "Failed to parse person.pb." << std::endl;
}
Instead of:
std::ostringstream out;
person.SerializeToOstream(&out);
QByteArray byteArray(out.str().c_str());
you can also write:
QByteArray byteArray(person.SerializeAsString().c_str());
EDIT: Above two gives the same result, but I'm not sure wether it's correct. This one seems to work better:
QByteArray byteArray(QString::fromStdString(person.SerializeAsString()));
EDIT2: OK, now I know how it works: first two ways are wrong if there are \0 char in serialization - everything after it it's then lost. To correct it one can write:
QByteArray byteArray(person.SerializeAsString().c_str(), person.ByteSize());
Using the code below is really dangerous
std::ostringstream out;
person.SerializeToOstream(&out);
QByteArray byteArray(out.str().c_str());
sendSerializedPersonOverQTcpSocket(byteArray);
You can find a good explanation here In protobuf-c, can optional uint32 variable have value 0
A right way to create a QByteArray from a protobuf message is
QByteArray byteArray;
byteArray.resize(message.ByteSize());
message.SerializeToArray(byteArray.data(), byteArray.size());
#James: You can use ParseFromArray(), for example, as below: (Please note that ParseFromArray() is available only on proto-buf-lite versions of the libs).
void convertQByteArrayToUser(QByteArray& aByteArray)
{
com::your::name_space::User user;
if(!user.ParseFromArray(aByteArray.data(), aByteArray.size()))
{
//could not parse
}
else { //yayyyyy
if(user.has_userid())
{
//...
}
}
}