Solved Build QImage from postgresql database via libpqxx
-
Hello. colleagues !
I have to build QImage object from bytea field of postgresql database, previously I do it using pqxx::binarystring as described in theme in here, but when pqxx::binarystring became deprecated and I have to use std::basic_string<std::byte> type instead, I have got invalid image with this, debug shows that binary string became different. Is it problem with libpqxx or Qt ?
-
@YuriyRusinov Please show your code.
-
Old code
pqxx::binarystring CVDbPgResult::getCellAsBinaryString0( int row, int column ) const { if( m_res == nullptr || row >= m_res->size() || column >= m_res->at(row).size() ) return pqxx::binarystring(nullptr, 0); pqxx::field fCell( m_res->at(row).at(column) ); pqxx::binarystring fCellB( fCell ); return fCellB; } int nn = getCellLength( row, column ); pqxx::binarystring imBytesStr0 = getCellAsBinaryString0( row, column ); const char* imBytes0 = imBytesStr0.get(); QByteArray imABytes = QByteArray::fromRawData( imBytes0, nn ); QImage resImage; bool isLoaded = resImage.loadFromData( imABytes );
New code:
basic_string<std::byte> imBytesStr = getCellAsBinaryString( row, column ); const void* imV = static_cast<const void*>(imBytesStr.data()); const char* imBytes = static_cast<const char *>(imV); std::basic_string<std::byte> CVDbPgResult::getCellAsBinaryString( int row, int column) const { if( m_res == nullptr || row >= m_res->size() || column >= m_res->at(row).size() ) return std::basic_string<std::byte>(nullptr, 0); pqxx::field fCell( m_res->at(row).at(column) ); pqxx::binarystring fCellB( fCell ); int nn = fCell.size(); const char* data = fCell.c_str(); qDebug() << __PRETTY_FUNCTION__ << nn << strlen(data) << fCellB.size(); const void* vData = static_cast<const void *>(data); const std::byte* vres(static_cast<const std::byte*>(vData)); // (data, nn);//get< std::string >(); std::basic_string<std::byte> res(vres); return res; }
-
I mean - it's clearly stated and obvious: So don't assume that it can be treated as a C-style string unless you've made sure of this yourself.
Use a proper container like e.g. std::vector<>
-
Therefore I need to use something like this vector<std::byte> or vector<char> ?
-
Thanks a lot, problem was solved, using libpqxx method pqxx::field::as< std::basic_string <std::byte> >();
std::basic_string<std::byte> CVDbPgResult::getCellAsBinaryString( int row, int column) const { if( m_res == nullptr || row >= m_res->size() || column >= m_res->at(row).size() ) return std::basic_string<std::byte>(nullptr, 0); pqxx::field fCell( m_res->at(row).at(column) ); return fCell.as< std::basic_string<std::byte> >(); }