문제

나는 현재 uiimageview에서 픽셀의 알파 값을 얻으려고 노력하고 있습니다. [uiimageview image]에서 cgimage를 얻었고 이것으로부터 RGBA 바이트 배열을 만들었습니다. 알파는 전형적입니다.

CGImageRef image = uiImage.CGImage;
NSUInteger width = CGImageGetWidth(image);
NSUInteger height = CGImageGetHeight(image);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
rawData = malloc(height * width * 4);
bytesPerPixel = 4;
bytesPerRow = bytesPerPixel * width;

NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(
    rawData, width, height, bitsPerComponent, bytesPerRow, colorSpace,
    kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big
);
CGColorSpaceRelease(colorSpace);

CGContextDrawImage(context, CGRectMake(0, 0, width, height), image);
CGContextRelease(context);

그런 다음 uiimageview의 좌표를 사용하여 주어진 알파 채널의 배열 인덱스를 계산합니다.

int byteIndex = (bytesPerRow * uiViewPoint.y) + uiViewPoint.x * bytesPerPixel;
unsigned char alpha = rawData[byteIndex + 3];

그러나 나는 내가 기대하는 가치를 얻지 못한다. 이미지의 완전히 검은 색 투명 영역의 경우 알파 채널에 대해 0이 아닌 값을 얻습니다. Uikit과 Core Graphics 사이의 코디네이트를 번역해야합니까? 즉, y 축은 뒤집어 졌습니까? 아니면 전술 한 알파 가치를 오해 했습니까?

업데이트:

@Nikolai Ruhe의 제안은 이것의 핵심이었습니다. 실제로 Uikit 좌표와 핵심 그래픽 좌표 사이를 번역 할 필요는 없었습니다. 그러나 블렌드 모드를 설정 한 후 알파 값이 예상했던 것입니다.

CGContextSetBlendMode(context, kCGBlendModeCopy);
도움이 되었습니까?

해결책

그렇습니다. 문서를 참조하십시오.

코드를 읽은 후 편집 :

또한 이미지의 알파 값이 아니라 이미지의 알파 값을 원하기 때문에 이미지를 그리기 전에 블렌드 모드를 교체하도록 설정하려고합니다.

CGContextSetBlendMode(context, kCGBlendModeCopy);

생각 후 편집 :

조회를 할 수 있습니다 많이 가능한 가장 작은 cgbitmapcontext (1x1 pixel? 아마 8x8? 시도 할 수 있음)를 구축하고 그리기 전에 원하는 위치로 컨텍스트를 번역함으로써 더 효율적입니다.

CGContextTranslateCTM(context, xOffset, yOffset);

다른 팁

당신이 원하는 것은 단일 지점의 알파 값이라면 알파 전용 단일 포인트 버퍼 만 있으면됩니다. 나는 이것이 충분해야한다고 믿는다 :

// assume im is a UIImage, point is the CGPoint to test
CGImageRef cgim = im.CGImage;
unsigned char pixel[1] = {0};
CGContextRef context = CGBitmapContextCreate(pixel, 
                                         1, 1, 8, 1, NULL,
                                         kCGImageAlphaOnly);
CGContextDrawImage(context, CGRectMake(-point.x, 
                                   -point.y, 
                                   CGImageGetWidth(cgim), 
                                   CGImageGetHeight(cgim)), 
               cgim);
CGContextRelease(context);
CGFloat alpha = pixel[0]/255.0;
BOOL transparent = alpha < 0.01;

uiimage를 매번 재현 할 필요가 없다면 이것은 매우 효율적입니다.

2011 년 12 월 8 일 편집 :

의견 제시자는 특정 상황에서 이미지가 뒤집을 수 있다고 지적합니다. 나는 이것에 대해 생각하고 있었고, UIIMAGE를 직접 사용하여 코드를 쓰지 않았기 때문에 미안합니다. UIGraphicsPushContext):

// assume im is a UIImage, point is the CGPoint to test
unsigned char pixel[1] = {0};
CGContextRef context = CGBitmapContextCreate(pixel, 
                                             1, 1, 8, 1, NULL,
                                             kCGImageAlphaOnly);
UIGraphicsPushContext(context);
[im drawAtPoint:CGPointMake(-point.x, -point.y)];
UIGraphicsPopContext();
CGContextRelease(context);
CGFloat alpha = pixel[0]/255.0;
BOOL transparent = alpha < 0.01;

나는 그것이 뒤집는 문제를 해결했을 것이라고 생각합니다.

직사각형 경계 상자가 아닌 이미지 데이터의 알파 값을 사용하여 스프라이트 간의 충돌 감지 방법을 연구 하면서이 질문/답변을 찾았습니다. 컨텍스트는 iPhone 앱입니다 ... 위의 제안 된 1 픽셀 드로우를하려고 노력하고 있으며 여전히 작동하는 데 문제가 있지만 이미지 자체의 데이터를 사용하여 CGContexTref를 만드는 데 더 쉬운 방법을 찾았습니다. 여기에 헬퍼 기능 :

CGContextRef context = CGBitmapContextCreate(
                 rawData, 
                 CGImageGetWidth(cgiRef), 
                 CGImageGetHeight(cgiRef), 
                 CGImageGetBitsPerComponent(cgiRef), 
                 CGImageGetBytesPerRow(cgiRef), 
                 CGImageGetColorSpace(cgiRef),
                 kCGImageAlphaPremultipliedLast     
    );

이것은 위의 샘플의 모든 못생긴 하드 코딩을 우회합니다. 마지막 값은 cgimagegetbitmapinfo ()를 호출하여 검색 할 수 있지만 내 경우에는 컨텍스트 크리징 함수에서 오류가 발생한 이미지에서 값을 반환합니다. 여기에 문서화 된대로 특정 조합 만 유효합니다. http://developer.apple.com/qa/qa2001/qa1037.html

이것이 도움이되기를 바랍니다!

Uikit과 Core Graphics 사이의 코디네이트를 번역해야합니까? 즉, y 축은 뒤집어 졌습니까?

있을 수있다. CGIMAGE에서 픽셀 데이터는 영어 읽기 순서 : 왼쪽에서 오른쪽, 상단에서 바닥입니다. 따라서 배열의 첫 번째 픽셀은 왼쪽 상단입니다. 두 번째 픽셀은 상단 행의 왼쪽에서 하나입니다. 등.

당신이 그 권리가 있다고 가정하면, 당신은 또한 픽셀 내의 올바른 구성 요소를보고 있는지 확인해야합니다. 아마도 당신은 RGBA를 기대하지만 ArgB를 요구하거나 그 반대도 마찬가지입니다. 또는 바이트 순서가 잘못되었을 수도 있습니다 (iPhone의 엔디 언이 무엇인지 모르겠습니다).

아니면 전술 한 알파 가치를 오해 했습니까?

처럼 들리지 않습니다.

모르는 사람들의 경우 : Pimultiplied는 색상 구성 요소가 알파에 의해 전형적임을 의미합니다. 알파 구성 요소는 색상 구성 요소가 전형적으로 배정되는지 여부에 관계없이 동일합니다. 색상 구성 요소를 알파로 나누어이를 (비 배상) 반전시킬 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top