Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Black and White BMP QImage distort
Forum Updated to NodeBB v4.3 + New Features

Black and White BMP QImage distort

Scheduled Pinned Locked Moved Solved General and Desktop
14 Posts 5 Posters 953 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • JustSoleSoleJ Offline
    JustSoleSoleJ Offline
    JustSoleSole
    wrote on last edited by
    #1

    Hi All,
    I need to transmit some black and white photos from my client to server,
    used QTcpServer and QTcpSocket.
    At the client i transfer the BMP data into QImage ,then QByteArray obj,and at the server i turn it back into QImage.
    I`m sure server has recive complete QByteArray,
    because i still have some color BMP photos that can be correctly turned into QImage and show on my server UI.
    So my question is why the Blacke&White ones strongly distort,but the color ones unaffected?

    //Client transfer code
    //QImage save to QByteArray
    QByteArray qbtImageArray;
    QBuffer qBuffer(&qbtImageArray);
    qImg->save(&qBuffer, "bmp");
    
    //Data length and index(for identify)
    NetImageDataHead objNet;
    objNet.nImageSize = qbtImageArray.size();
    objNet.nImageIndex = pNetDeviceParams->nIndex;
    
    //Append head and data
    QByteArray qbtMsgArray;
    qbtMsgArray.append((char *)&objNet, sizeof(NetImageDataHead));
    qbtMsgArray.append(qbtImageArray);
    
    //Server code
    //QByteArray to QImage
     QBuffer buffer(&qbImgData);
    QImageReader reader(&buffer, "bmp");
    QImage img = reader.read();
    pLabel->setPixmap(QPixmap::fromImage(img));
    
    1 Reply Last reply
    0
    • JustSoleSoleJ Offline
      JustSoleSoleJ Offline
      JustSoleSole
      wrote on last edited by
      #14

      Finally,this problem solved.
      I checked the QImage::Format enum,found this:

      QImage::Format_Indexed8:
      The image is stored using 8-bit indexes into a colormap.
      

      Feeling something wrong then i found:

      QImage::Format_Grayscale8
      The image is stored using an 8-bit grayscale format. 
      

      This format should be what i need,but not Index8.
      So i tried to convert my unsigned char* img data into QImage by this format, and transmit the formed QByteArray data to server and convert it back to QImage ,and it works!!!
      The conclusion of create a black and white BMP QImage is use QImage::Format_Grayscale8.
      And thank you all for your help.Really appreciate!!!

      1 Reply Last reply
      1
      • Christian EhrlicherC Online
        Christian EhrlicherC Online
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on last edited by
        #2

        And now, as said in my previous post, please show us how you send and receive the data

        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
        Visit the Qt Academy at https://academy.qt.io/catalog

        1 Reply Last reply
        0
        • JustSoleSoleJ Offline
          JustSoleSoleJ Offline
          JustSoleSole
          wrote on last edited by
          #3

          Client uses QTcpSocket

          //Client transfer code
          //QImage save to QByteArray
          QByteArray qbtImageArray;
          QBuffer qBuffer(&qbtImageArray);
          qImg->save(&qBuffer, "bmp");
          
          //Data length and index(for identify)
          NetImageDataHead objNet;
          objNet.nImageSize = qbtImageArray.size();
          objNet.nImageIndex = pNetDeviceParams->nIndex;
          
          //Append head and data
          QByteArray qbtMsgArray;
          qbtMsgArray.append((char *)&objNet, sizeof(NetImageDataHead));
          qbtMsgArray.append(qbtImageArray);
          
          //QTcpSocket write
          m_objTcpClient->write(qbtMsgArray);
          

          Server inherits QTcpServer and QTcpSocket to make QTcpSocket can be used in QThread,and set a slot to read the data.

          void QPxTcpSocket::Slot_ThisReadData()
          {
          	Qt::HANDLE hThreadId = QThread::currentThreadId();
          	qDebug() << "TcpServerThreadId = " << hThreadId;
          
          	int nRevMsgSize = this->bytesAvailable();
          	//Read head data first, m_bIsHead is initialised to be true
          	if (m_bIsHead)
          	{
          		if (nRevMsgSize < sizeof(NetImageDataHead))
          		{
          			return;
          		}
          		//read Image data
          		m_bIsHead = false;
          		QByteArray qbtHeadArray;
          		qbtHeadArray.append(this->read(sizeof(NetImageDataHead)));
          		NetImageDataHead * pNetDeviceParam = (NetImageDataHead *)qbtHeadArray.data();
          		if (pNetDeviceParam)
          		{
          			m_nImageDataSize = pNetDeviceParam->nImageSize;
          			m_nImageDataIndex = pNetDeviceParam->nImageIndex;
          		}
          		qbtHeadArray.clear();
          	}
                  //then read Image data
          	else
          	{
                          //m_objMsgData is QByteArray
          		if (m_nImageDataSize > nRevMsgSize)
          		{
          			m_objMsgData.append(this->read(nRevMsgSize));
          			m_nImageDataSize -= nRevMsgSize;
          		}
          		else
          		{
          			double dFps = m_objFps.CaculateFps();
          			m_objMsgData.append(this->read(m_nImageDataSize));
          			//emit Signal_ShowClientImage1(m_objMsgData, dFps);
          			emit Signal_ShowClientImage(m_qnSocketID, m_objMsgData, dFps);
          
          			m_nImageDataSize = 0;
          			m_objMsgData.clear();
          			m_bIsHead = true;
          		}
          	}
          }
          

          Should and how can i upload more details is better?
          Really appreciate your help!

          1 Reply Last reply
          0
          • Christian EhrlicherC Online
            Christian EhrlicherC Online
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on last edited by
            #4

            This all looks fine. To be sure I would add some debug output - e.g. the md5 sum (or any other checksum) when sending the data/ when you converted it from a QImage and then after you received it / try to convert it to a QImage just to be sure you really got all data.

            I can think about threading issues here - a thread is not really needed and also no custom QTcpSocket.

            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
            Visit the Qt Academy at https://academy.qt.io/catalog

            1 Reply Last reply
            0
            • JustSoleSoleJ Offline
              JustSoleSoleJ Offline
              JustSoleSole
              wrote on last edited by
              #5

              @Christian-Ehrlicher
              Like what i write before, i have two kinds of image data, one is colorful BMP image, this format can be convert back into QImage and show correctly on my server UI.
              But the Black and white one, before i send data, i checked the data length,after server recviced the data, i checked the data length before convert it to QImage.And the result is these two length are all the same.But the QImage data is just distort...

              About the thread question,it`s because i have two camera ,i need to make them send both format data at the same time.And my server need to show these two different image at the same time.
              If i dont use threads,there will be a very high delay.Even if i only open just one camera.

              Now im trying to use char* to trasmit my B&W format img data directly.Later we will know if it works.Wish me successful.

              And if you have any other suggestions, plz tell me i`ll learn and give them a try.
              Thank you for your advice!

              1 Reply Last reply
              0
              • C Offline
                C Offline
                ChrisW67
                wrote on last edited by
                #6

                @JustSoleSole said in Black and White BMP QImage distort:

                But the QImage data is just distort...

                What does this actually mean? Can you post a good and bad image.

                JustSoleSoleJ 1 Reply Last reply
                0
                • C ChrisW67

                  @JustSoleSole said in Black and White BMP QImage distort:

                  But the QImage data is just distort...

                  What does this actually mean? Can you post a good and bad image.

                  JustSoleSoleJ Offline
                  JustSoleSoleJ Offline
                  JustSoleSole
                  wrote on last edited by
                  #7

                  @ChrisW67
                  Normal black and white img:
                  NormalImg.png

                  Distort abnormal one:
                  AbnormalImg.png

                  1 Reply Last reply
                  0
                  • JustSoleSoleJ Offline
                    JustSoleSoleJ Offline
                    JustSoleSole
                    wrote on last edited by
                    #8

                    I tried to give give QImage a format before i read the img data from QByteArray which is transmitted to server.

                    //Server code
                    //qbImgData is QByteArray that is transmitted from client
                    QBuffer buffer(&qbImgData);
                    QImageReader reader(&buffer, "bmp");
                    //this line is the one i add before read img, black&white img is 1 bit per pixel.
                    //At the memory 8bits are saved in one byte.
                    QImage img(808, 608, QImage::Format_Indexed8);
                    reader.read(&img);
                    

                    With this effort.This two pics seem to be more clear and intuitional.
                    B&WA.png
                    B&WB.png
                    You can see the abnormal one is not only distort but also seems to be cut into two reversed parts.
                    But now i dont know how to make it more clear.

                    1 Reply Last reply
                    0
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #9

                      Hi,

                      What is the exact format of your B&W image ? Bitmap ? Raw ? JPEG ?

                      Interested in AI ? www.idiap.ch
                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                      JustSoleSoleJ 1 Reply Last reply
                      0
                      • SGaistS SGaist

                        Hi,

                        What is the exact format of your B&W image ? Bitmap ? Raw ? JPEG ?

                        JustSoleSoleJ Offline
                        JustSoleSoleJ Offline
                        JustSoleSole
                        wrote on last edited by
                        #10

                        @SGaist
                        BMP,if i put the data in a string or in a bytearray,its beginning two words are 'B' and 'M',which should stands for the BMP format.
                        byteArray.png

                        1 Reply Last reply
                        0
                        • JustSoleSoleJ Offline
                          JustSoleSoleJ Offline
                          JustSoleSole
                          wrote on last edited by
                          #11

                          And I tried to use QDataStream to convert QImage to QByteArray,in this way when the QByteArray convert back to QImage, it works...The QImage doesnt distort and shows good.But this way consume too much time,dealing with one frame needs about 130ms.
                          Code:

                          	QByteArray qbtMsgArray;
                          	QDataStream in(&qbtMsgArray, QIODevice::ReadWrite);
                          	in << *qImg;
                          	qDebug() << qbtMsgArray;
                          
                          	QDataStream out(&qbtMsgArray, QIODevice::ReadWrite);
                          	QImage tImg;
                          	out >> tImg;
                          

                          I print the QByteArray and it shows this:
                          HexDataStreamArray.png
                          And the faster way:

                          	QByteArray qbtImageArray;
                          	QBuffer qBuffer(&qbtImageArray);
                          	//qImg->save(&qBuffer, "bmp", 100);
                          	qDebug() << qbtImageArray;
                          	QBuffer buffer(&qbtImageArray);
                          	QImageReader reader(&buffer, "bmp");
                          	QImage img(808, 608, QImage::Format_Indexed8);
                          	reader.read(&img);
                          

                          I print the QByteArray and it shows this:
                          HexSaveBTArray.png

                          Why are they so different...

                          1 Reply Last reply
                          0
                          • JoeCFDJ Offline
                            JoeCFDJ Offline
                            JoeCFD
                            wrote on last edited by
                            #12

                            the source code is here. You check the differences out.
                            https://code.qt.io/cgit/qt/qtbase.git/tree/src/gui/image/qimage.cpp?h=dev

                            JustSoleSoleJ 1 Reply Last reply
                            0
                            • JoeCFDJ JoeCFD

                              the source code is here. You check the differences out.
                              https://code.qt.io/cgit/qt/qtbase.git/tree/src/gui/image/qimage.cpp?h=dev

                              JustSoleSoleJ Offline
                              JustSoleSoleJ Offline
                              JustSoleSole
                              wrote on last edited by
                              #13

                              @JoeCFD
                              I`ve already checked yesterday,
                              I see no much differences between QDataStream operator<<() and QImage save().
                              And now i find if i use privious saved BMP file as source data, do QImage save and QImageReader read,the new QImage pic doesnt distort.
                              But if i use real-time img source data like snap by a camera, the it doesnt work.
                              So im now checking the source data to see if it can help.

                              1 Reply Last reply
                              0
                              • JustSoleSoleJ Offline
                                JustSoleSoleJ Offline
                                JustSoleSole
                                wrote on last edited by
                                #14

                                Finally,this problem solved.
                                I checked the QImage::Format enum,found this:

                                QImage::Format_Indexed8:
                                The image is stored using 8-bit indexes into a colormap.
                                

                                Feeling something wrong then i found:

                                QImage::Format_Grayscale8
                                The image is stored using an 8-bit grayscale format. 
                                

                                This format should be what i need,but not Index8.
                                So i tried to convert my unsigned char* img data into QImage by this format, and transmit the formed QByteArray data to server and convert it back to QImage ,and it works!!!
                                The conclusion of create a black and white BMP QImage is use QImage::Format_Grayscale8.
                                And thank you all for your help.Really appreciate!!!

                                1 Reply Last reply
                                1

                                • Login

                                • Login or register to search.
                                • First post
                                  Last post
                                0
                                • Categories
                                • Recent
                                • Tags
                                • Popular
                                • Users
                                • Groups
                                • Search
                                • Get Qt Extensions
                                • Unsolved