Kenogu Labz이 다른 답변에서 언급했듯이 색상 일치는 정확하지만 이미지 가장자리 주변의 색상이 원본 이미지 코덱에 의해 앤티 엘리 어싱되거나 저하됩니다 (손실 이미지 압축 시스템의 일반적인 문제). JPEG와 같은).
정확한 색상 일치를 수행하는 대신 색상 범위과 일치해야합니다.
이 작업을 수행하는 가장 좋은 방법은 대개 색상이 얼마나 가까이 있어야하는지에 대한 허용 오차를 설정하는 것입니다. 당신은 SameColor()
에 대한 코드를 나열하지 않은하지만 당신은 아마 지금과 같은 구현 뭔가 SimilarColor()
에 SameColor()
을 변경하여 원하는 결과를 얻을 수 있습니다 :
bool SimilarColor(color c1, color c2, int tolerance)
{
int rDiff = std::abs(c1.r - c2.r);
int gDiff = std::abs(c1.g - c2.g);
int bDiff = std::abs(c1.b - c2.b);
return (rDiff < tolerance && gDiff < tolerance && bDiff < tolerance);
}
NB합니다. 이것은 의사 코드입니다. 나는 이제 나의 답변에 ALLEGRO 호환 구현을 추가했다.
일반적으로 빨간색 차이, 녹색 차이 및 파란색 차이를 계산하고 허용 오차 값 아래에 있는지 확인해야합니다. 이 경우, true를 리턴하고 색상 대체를 수행하고, 대체가 수행되지 않으면 대체가 수행됩니다. 전문가를위한
추가 :
하는 것이 더 좋은 결과를 얻으려면, 당신은 수 있도록 (자신의 채도 값을 유지)를 직접 일치하는 색상을 교체하는 대신 일치하는 픽셀의 색상을 변경하지 않는 것을 고려할 수 있습니다 색상이 바뀐 이미지가 지나치게 단순화되지 않습니다. 이 경우 색상 1과 색상 2에 H, S, V 값이 필요하며 이는 ALLEGRO에서 직접 지원되거나 사용자 정의 코드가 필요할 수 있습니다.
일부 추가 의견
주 당신의 현재 코드 방문 이미지의 모든 픽셀. 이미지의 일부 의도하지 않은 임의의 픽셀이 허용치 내에서 의도하지 않게 색칠 될 수 있습니다.
피하기 위해 FloodFill (즉, 페인트 킷) 유형의 색 재현을 대체 할 수 있습니다 (더 복잡하고 재색 영역을 연속 영역으로 제한 함). 또는 메모리 이미지에서 작업 할 수도 있습니다 여기서 각각의 재현 가능한 섹션은 고유 한 앨리어싱되지 않은 픽셀 색상을 갖도록 미리 준비되어 있습니다. 예를 들어 메모리 내 버퍼에 rgb (0,255,0) 녹색면이있는 소스 이미지를 가질 수 있지만 선택한 색조로 다시 칠해진 얼굴을 표시 할 수 있습니다.그리고 사용자가 색상을 변경하기로 선택하면 원래의 녹색 이미지를 다시 색칠하십시오. 희망은 그 말이 맞습니다.
사이드 참고 : 당신이 때문에 이미지의 파일 형식으로 사진 저하를 방지하려면 항상 .jpg
에 .png
파일을 선호 여기에 내가 설명하고있는 오프 스크린 소스 이미지의 예입니다.
최상의 결과를 얻으려면 위에서 설명한 색상 키 이미지를 사용하는 것이 좋습니다. 원본 이미지를 조작하고 .png
과 같은 무손실 파일 형식으로 저장할 수 있으므로 원본 코드와 똑같은 색상 일치를 수행 할 수 있고 색상 범위를 시도하거나 일치시킬 필요가 없다는 장점이 있습니다. 또한 배경색이 허용치에 너무 가까워서 실수로 색상이 바뀌는 상황이 발생하지 않습니다.
그러나 ALLEGRO_COLOR에 대한 ALLEGRO 설명서를 살펴 보았으며 다음 방법은 해당 라이브러리를 사용하여 위에 표시된 SimilarColor 메서드를 수행해야합니다. 알레그로에서 당신이 직접 ALLEGRO_COLOR의 개별 구성 요소에 액세스 할 수 없습니다 나타납니다, 그래서 당신은 al_unmap_rgb
먼저 수행해야합니다
bool SimilarColor(ALLEGRO_COLOR c1, ALLEGRO_COLOR c2, int tolerance)
{
// unpack the colors into their r,g,b components:
unsigned char c1R, c1G, c1B, c2R, c2G, c2B;
al_unmap_rgb(c1, &c1R, &c1G, &c1B);
al_unmap_rgb(c2, &c2R, &c2G, &c2B);
// calculate the absolute red, green and blue differences:
int rDiff = std::abs((int)c1R - (int)c2R);
int gDiff = std::abs((int)c1G - (int)c2G);
int bDiff = std::abs((int)c1B - (int)c2B);
// return true only if ALL color channel diffs are below tolerance.
// NB. tolerance needs to be between 1 and 254, and a value of 35
// is probably a good start point for testing purposes
return (rDiff < tolerance && gDiff < tolerance && bDiff < tolerance);
}
어떤 특정 언어/환경? –
예 C++ 및 Allegro – Claudia