2012-06-13 3 views
0

만약 내가 다음 사용하여 Qt를 수행 QImage :: Format_RGB32에서왜 RGB888에서 RGB565로 변환하면 색상 손실이 발생합니까?

  1. 로드 비트 맵을.
  2. 픽셀을 RGB565로 변환하십시오 (Qt 형식이 아니므로 "손으로"해야 함).
  3. 새로운 맵 1.
  4. 3.이
  5. 4 단계에서 생성 된 화상이 보이는 단계에서 생성 된 화상에 다시 RGB88에 RGB565 버퍼 화소 변환 단계에 들어있는 것과 같은 크기로 만들기 RGB 값을 비교할 경우 정확하게 동일하지는 않습니다.

2 ~ 5 단계를 반복하면 최종 이미지의 색상이 줄어들어 어두워지고 어두워집니다.

qRgb RGB565ToRGB888(unsigned short int aTextel) 
{ 
    unsigned char r = (((aTextel)&0x01F) <<3); 
    unsigned char g = (((aTextel)&0x03E0) >>2); 
    unsigned char b = (((aTextel)&0x7C00)>>7); 
    return qRgb(r, g, b, 255); 
} 

unsigned short int RGB888ToRGB565(QRgb aPixel) 
{ 
    int red = (aPixel >> 16) & 0xFF; 
    int green = (aPixel >> 8) & 0xFF; 
    int blue = aPixel & 0xFF; 

    unsigned short B = (blue >> 3) & 0x001F; 
    unsigned short G = ((green >> 2) < 5) & 0x07E0; 
    unsigned short R = ((red >> 3) < 11) & 0xF800; 

    return (unsigned short int) (R | G | B); 
} 

4278190080.

편집으로 RGB888로 RGB565에서 다시 변환됩니다 4278192128입니다 제대로 변환하지 않습니다 내 테스트 이미지에서 발견 예 : 여기

내 변환 기능이 있습니다 : 원본 소스 데이터가 RGB565 (내 테스트 RGB888 이미지가 생성 된 것임)라고도 언급해야합니다. 디스플레이 목적으로 만 RGB888로 변환 중이지만 두 개의 데이터 복사본을 유지하는 대신 나중에 RGB565로 변환하고 싶습니다.

+5

5 또는 6 비트는 8과 동일한 값 범위를 유지할 수 없습니다. 변환은 손실이 많으므로 앞뒤로 변환 할 필요가 없도록 디자인을 재고해야합니다. –

+1

<5) 및 <11) : << 5 및 << 11이 아니어야합니까? – teambob

+0

나는 여분의 <어떤 식 으로든 붙여 넣기에서 제거 된 것 같아요 – paulm

답변

8

미리 두 개의 변환 함수에서 구성 요소 순서가 같지 않음을 말씀드립니다. 565 -> 888 변환에서는 빨간색 구성 요소가 하위 비트 (0x001F)를 사용한다고 가정하지만 빨간색 구성 요소의 5 비트를 인코딩 할 때는 상위 비트 (0xF800)에 배치합니다. 0xAARRGGBB (RGB565의 이진 표현은 0bRRRRRGGGGGGBBBBB)과 비슷한 구성 요소 주문을 원할 경우 RGB565ToRGB888 메서드에서 변수 이름을 변경해야합니다. 아래 코드에서이 문제를 해결했습니다.

RGB565에서 RGB888 로의 변환이 버그입니다. 초록색 채널의 경우 5 비트를 추출하여 결과에 8 비트 대신 7 비트 만 제공합니다. 파란색 채널의 경우 다음과 같은 비트를 가져 오며 이는 결과 오류입니다. 이 문제를 해결해야합니다 :

QRgb RGB565ToRGB888(unsigned short int aTextel) 
{ 
    // changed order of variable names 
    unsigned char b = (((aTextel)&0x001F) << 3); 
    unsigned char g = (((aTextel)&0x07E0) >> 3); // Fixed: shift >> 5 and << 2 
    unsigned char r = (((aTextel)&0xF800) >> 8); // shift >> 11 and << 3 
    return qRgb(r, g, b, 255); 
} 

다른 기능에서는 실수로 왼쪽 쉬프트 연산자 대신 less 연산자를 썼습니다. 이것은 문제를 해결한다 : 당신이 이미 존재하는 (인라인)를 사용할 수 있습니다

unsigned short int RGB888ToRGB565(QRgb aPixel) 
{ 
    int red = (aPixel >> 16) & 0xFF; // why not qRed(aPixel) etc. ? 
    int green = (aPixel >> 8) & 0xFF; 
    int blue = aPixel  & 0xFF; 

    unsigned short B = (blue >> 3)  & 0x001F; 
    unsigned short G = ((green >> 2) << 5) & 0x07E0; // not < 
    unsigned short R = ((red >> 3) << 11) & 0xF800; // not < 

    return (unsigned short int) (R | G | B); 
} 

주 기능 qRed, 구성 요소에서 컬러 건설 qRgb 유사한 구성 요소 추출을위한 qGreen, qBlue.

RGB888ToRGB565의 최종 비트 마스크는 구성 요소 값이 8 비트 범위에 있으므로 선택 사항이며 먼저 값을 오른쪽으로 이동 한 다음 왼쪽 시프트로 자릅니다.

+0

또한 녹색 구성 요소에 대해 3 씩 2 씩 시프 팅을 변경해야했습니다 (RGB888ToRGB565에서). 이제 300 회 전환 후 이미지가 약간 어두워 지지만 점진적으로 어두워지는 것은 아닙니다. – paulm

+0

RGB565ToRGB888 함수에서 2가되어서는 안되며, 많은 변환 후에 픽셀이 완벽하게 동일합니다. – paulm

관련 문제