본문 바로가기
QT and Symbian

QImage Format 중 QImage::Format_Mono 처리 방식

by leo21c 2015. 1. 30.

참고자료:
http://stackoverflow.com/questions/13754099/working-with-monochrome-qimage

uchar * QImage::scanLine(int i)
Returns a pointer to the pixel data at the scanline with index i. The first scanline is at index 0.

The scanline data is aligned on a 32-bit boundary.

Warning: If you are accessing 32-bpp image data, cast the returned pointer to QRgb* (QRgb has a 32-bit size) and use it to read/write the pixel value. You cannot use the uchar* pointer directly, because the pixel format depends on the byte order on the underlying platform. Use qRed(), qGreen(), qBlue(), and qAlpha() to access the pixels.

위의 경고를 확인하고 mono QImage는 getPixel, setPixel 함수를 이용해서 처리를 해야하나 고민을 했었다.
32bit 일경우에는 QRgb로 타입 캐스팅을 해야 하지만 그렇지 않으면 uchar*로 리턴되어 처리가 가능하다고 한다.

아래 예제는 monochrome QImage to a cv::Mat로 변경하는 방식이다.

QImage mask; //Input from wherever
cv::Mat workspace;
if(!mask.isNull() && mask.depth() == 1)
{
    if(mask.width() != workspace.cols || mask.height() != workspace.rows)
        workspace.create(mask.height(), mask.width(), CV_8UC1);

    for(int i = 0; i < mask.height(); ++i)
    {
        unsigned char * cur_row = mask.scanLine(i);
        //for(int cur_byte = 0, j = 0; cur_byte < mask.bytesPerLine(); ++cur_byte) wrong
        for(int cur_byte = 0, j = 0; j < mask.width(); ++cur_byte)
        {
            unsigned char pixels = cur_row[cur_byte];
            for(int cur_bit = 0; cur_bit < 8; ++cur_bit, ++j)
            {
                if(pixels & 0x01) //Least Significant Bit
                    workspace.at<unsigned char>(i, j) = 0xff;
                else
                    workspace.at<unsigned char>(i, j) = 0x00;
                 pixels = pixels >> 1; //Least Significant Bit
            }
        }
     }
 }