uiimageview에서 픽셀 데이터 얻기 - 장치가 아닌 시뮬레이터에서 작동합니다.

StackOverflow https://stackoverflow.com/questions/1911360

  •  19-09-2019
  •  | 
  •  

문제

응답을 기반으로합니다 이전 질문, 픽셀 데이터를 추출하기 위해 uiimageview에서 카테고리를 만들었습니다. 이것은 시뮬레이터에서는 잘 작동하지만 장치에 배치 된 경우에는 그렇지 않습니다. 나는 말하지 말아야한다 언제나 - 이상한 점은 point.x == point.y 인 경우 올바른 픽셀 색상을 가져 오는 것입니다. 그렇지 않으면, 그것은 마치 마치 마치 마치 마치 해당 라인의 다른쪽에있는 픽셀에 대한 픽셀 데이터를 제공합니다. (따라서 이미지의 오른쪽 하단 코너에있는 픽셀을 탭하면 왼쪽 상단의 해당 픽셀에 대한 픽셀 데이터를 제공하지만 왼쪽 하단 코너의 픽셀을 탭하면 올바른 픽셀 색상이 반환됩니다). 터치 좌표 (CGPoint)가 정확합니다.

내가 뭘 잘못하고 있죠?

내 코드는 다음과 같습니다.

@interface UIImageView (PixelColor)
- (UIColor*)getRGBPixelColorAtPoint:(CGPoint)point;
@end

@implementation UIImageView (PixelColor)

- (UIColor*)getRGBPixelColorAtPoint:(CGPoint)point
{
    UIColor* color = nil;

    CGImageRef cgImage = [self.image CGImage];
    size_t width = CGImageGetWidth(cgImage);
    size_t height = CGImageGetHeight(cgImage);
    NSUInteger x = (NSUInteger)floor(point.x);
    NSUInteger y = height - (NSUInteger)floor(point.y);

    if ((x < width) && (y < height))
    {
        CGDataProviderRef provider = CGImageGetDataProvider(cgImage);
        CFDataRef bitmapData = CGDataProviderCopyData(provider);
        const UInt8* data = CFDataGetBytePtr(bitmapData);
        size_t offset = ((width * y) + x) * 4;
        UInt8 red = data[offset];
        UInt8 blue = data[offset+1];
        UInt8 green = data[offset+2];
        UInt8 alpha = data[offset+3];
        CFRelease(bitmapData);
        color = [UIColor colorWithRed:red/255.0f green:green/255.0f blue:blue/255.0f alpha:alpha/255.0f];
    }

    return color;
}
도움이 되었습니까?

해결책

나는 r을 생각한다 BG 잘못되었습니다. 당신은 :

UInt8 red =   data[offset];     
UInt8 blue =  data[offset+1];
UInt8 green = data[offset+2];

그러나 당신은 정말로 r을 의미하지 않습니다 GB? :

UInt8 red =   data[offset];     
UInt8 green = data[offset+1];
UInt8 blue =  data[offset+2];

하지만 그 수정에도 불구하고 사과가 나오는 것처럼 여전히 문제가 있습니다. 바이트 스왑 (훌륭한 기사) 장치에있을 때 R과 B 값이지만 ~ 아니다 시뮬레이터에있을 때.

CFDATAGETBYTEPTR에 의해 반환 된 PNG의 픽셀 버퍼와 비슷한 시뮬레이터/장치 문제가있었습니다.

이것은 나에게 문제를 해결했다.

#if TARGET_IPHONE_SIMULATOR
        UInt8 red =   data[offset];
        UInt8 green = data[offset + 1];
        UInt8 blue =  data[offset + 2];
#else
        //on device
        UInt8 blue =  data[offset];       //notice red and blue are swapped
        UInt8 green = data[offset + 1];
        UInt8 red =   data[offset + 2];
#endif

이것이 문제를 해결하는지 확실하지 않지만 오작동 코드는 내가 수정하기 전에 내 모습에 가깝게 보입니다.

마지막으로 : 시뮬레이터를 사용하면 픽셀 버퍼에 액세스 할 수 있다고 생각합니다. data[] 이후에도 CFRelease(bitmapData) 호출됩니다. 장치에서 이것은입니다 ~ 아니다 내 경험의 경우. 코드에 영향을 미치지 않아야하지만 다른 사람이 언급했다고 생각하는 경우에도 도움이됩니다.

다른 팁

다음 대안 접근법을 시도 할 수 있습니다.

  • cgbitmapcontext를 만듭니다
  • 이미지를 컨텍스트로 그립니다
  • 컨텍스트에서 cgbitmapcontextgetData에 전화하여 기본 데이터를 얻으십시오.
  • 비트 맵 컨텍스트를 작성한 방법에 따라 오프셋을 원시 데이터로 확인하십시오.
  • 값을 추출하십시오

이 접근법은 시뮬레이터와 장치에서 저에게 효과적입니다.

대신 원래 질문에 게시 된 코드에있는 것 같습니다.

NSUInteger x = (NSUInteger)floor(point.x);
NSUInteger y = height - (NSUInteger)floor(point.y);

그것은해야한다:

NSUInteger x = (NSUInteger)floor(point.x);
NSUInteger y = (NSUInteger)floor(point.y);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top