2009-11-28 5 views
1

최근에는 메모리에 비 압축 비트 맵을 표시하는 데 관심이있었습니다. 그러나 올바르게 구현하는 방법을 모르는 한 가지는 바이너리 투명성입니다. 예, 나는 이런 식으로 시작 : 이진 투명도를 나타내는 방법은 무엇입니까?

struct RGBPixel { 
uint8_t red; 
uint8_t green; 
uint8_t blue; 
}; 

struct bitmap { 
struct RGBPixel *data; 
size_t width; 
size_t height; 
size_t bytesPerPixel; 
size_t bytewidth; 
/* etc. */ 
}; 

내가 가장 간단한 방법이 될 것입니다 가정 :

struct RGBPixel { 
uint8_t red; 
uint8_t green; 
uint8_t blue; 
bool transparent; 
}; 

을하지만 그건 조금 낭비 것 (당신은뿐만 아니라 전체 알파 채널을 추가 할 수 있습니다) . 내가 생각할 수있는 유일한 다른 가능성은 색상 중 하나를 투명하게 유지하지만 그 색상을 표시하는 기능을 잃어 버리는 것입니다. 이것을하기위한 표준 방법이 있습니까?

일반적인 형식 (GIF, 8 비트 PNG 등)은 어떻게 나타 납니까?

답변

1

큰 어려움되지 않습니다 투명 중 하나를 지정 16M 색상이 있습니다. 이미지가 16 메가 픽셀이 아니라면 16M의 모든 색상을 사용하지 않을 수도 있습니다. 사용되지 않는 이미지를 선택하여 투명도 색상으로 지정하십시오. 그 (것)들을 모두 사용하는 거대한 이미지가 있다면, 사용량이 가장 적은 이미지를 선택하고 인접한 컬러로 변경하여 사용하지 않도록하십시오.

위에서 말씀 드린대로 픽셀 RGB 데이터로 픽셀 당 하나의 비트를 저장하려고하면 효율적이지 않습니다. 아마 모든 RGB 픽셀을 하나의 포인터에 저장 한 다음 다른 H 및 V 치수의 비트 맵을 다른 포인터에 저장하거나 크로마 키잉을 수행해야합니다.위에서 언급 한 바와 같이 R, G, B 및 투명도 비트 맵을 사용하여 데이터를 개별적으로 저장할 수는 있지만 그리기에는 일반적으로 매우 비효율적입니다.

+0

"그냥 사용되지 않는 하나를 선택하여 투명도 색상으로 만드십시오." 하지만이 색을 어떻게 선택해야합니까? 이미지를 반복하여 사용하지 않을 때까지 색상을 추측 해 둡니다. – Sam

+0

사용하지 않을 것으로 생각되는 색상부터 시작하십시오. Loop Through를 사용한다면, 픽스맵을 사용하여 오프셋을 기억하고, 색상을 약간 변경하고 (아마도 B 값을 증가시키고, G를 R로 적당히 굴림) 픽스맵의 끝까지 반복하고 시작합니다. 다시 시작하면이 색을 찾지 못하면 그 색이됩니다. 그렇지 않으면 반복하십시오. 더 나은 코너 케이스 성능을 위해서는 처음에는 사용하지 않을 256 색을 선택하고 동시에 검색하십시오. 사용중인 모든 것을 찾을 확률은 4MP 이미지에서 1/4^256 또는 1e25에 약 1입니다. –

1

GIF는 투명을 위해 지정된 색을 사용합니다. (예 : 0xFFFF00이 투명하다고 말하면이 색상의 모든 픽셀이 투명하게 표시됩니다.)이 색상은이 이미지에서 사용할 수 없습니다.
Png에는 알파 채널이 있습니다. 이는 픽셀의 알파 값을 나타내는 또 다른 int를 의미합니다. (예 : 0 = 완전히 투명, 불투명 = 255, 128 = 반투명)

+0

어떤 색을 사용합니까? – Sam

+1

GIF는 직접 색이 아닌 인덱스 색을 사용합니다. 그래서 각 픽셀은 RGB 색상 룩업 테이블에 대한 인덱스 인 256 가지 색상 중 하나로 인코딩됩니다. 투명도를 원하면 이미지를 255 색으로 줄이고 나머지 인덱스는 투명도를 나타 내기 위해 사용됩니다. –

+0

그 오른쪽 @ 남부 접대, 전 단지 특정 픽셀을 투명하게 정의하는 2 가지 방법을 보여주고 싶었어요. – TheHippo

0

일반적으로 투명성을 표현하는 네 번째 알파 채널이있다.

즉 RBG 대신 RGBA를 사용할 수 있습니다.

0

이진 투명도는 크로마 키잉이라고도합니다. 색상을 투명 색상으로 지정하고 색상이 채색 키 (투명 색상으로 지정)가 아닌 경우 도면 기능에서 픽셀을 그립니다.

픽셀 당 알파는 그림자 제거와 같은 다중 레벨 투명도를 수행 할 때 사용됩니다.

당신은 예를 들어, 별도의 메모리에 투명성을 저장, 또는 개별적으로 각 채널을 저장할 수
0

:

struct bitmap { 
uint8_t *red; 
uint8_t *green; 
uint8_t *blue; 
uint8_t *transparency; 
// or packed: uint8_t *RGB, *transparency; 
size_t width; 
size_t height; 
}; 

그런 다음 투명도 채널 width*height/8 바이트를 할당하고, 컬러 채널 당 8 개 비트를 가정하면 비트에 액세스 할 수 있습니다 다음과 같이하십시오 :

bool get_transparency(struct bitmap* bmp, size_t x, size_t y) { 
    size_t idx = y * bmp->width + x; 
    size_t tidx = idx >> 3; // = idx/8 
    uint8_t t8 = (uint8_t)(idx & 7); // = idx % 8 
    uint8_t mask = 1 << t8; 
    return (bmp->transparency[tidx] & mask) != 0; 
} 

참고 : 비트 액세스는 최적화 될 수 있습니다.

또 다른 해결책 : 컬러 채널 중 하나의 비트를 스 와이프와 같은 당신의 구조체를 정의 할 수 있습니다 : 저장 또는 빨강 채널을 읽을 때

struct RGBPixel { 
uint8_t red : 7; 
uint8_t transparency : 1; 
uint8_t green; 
uint8_g blue; 
}; 

, 당신은 그에 따라 예를 확장 할 수 있습니다 red = (uint8_t)(((uint16_t)pix->red * 8)/7);