IOS, не могу получить правильный цвет пикселя CGImageRef
Я сделал контекст, затем градиент. После этого я подхожу к контексту. Затем я получаю градиентное изображение из контекста, и это правильно, я вижу это в отладчике. Но когда я пытаюсь получить цвет пикселя для определенного значения, это не правильно. Я ценю любую помощь, спасибо. Вот код
- (UIColor*) getColorForPoint: (CGPoint) point imageWidth: (NSInteger) imageHeight
{
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
// create a gradient
CGPoint startPoint = CGPointMake(0, 0);
CGPoint endPoint = CGPointMake(imageHeight, 0);
// create a bitmap context to draw the gradient to, 1 pixel high.
CGContextRef context = CGBitmapContextCreate(NULL, imageHeight, 1, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);
// draw the gradient into it
CGContextAddRect(context, CGRectMake(0, 0, imageHeight, 1));
CGContextClip(context);
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
// Get our RGB bytes into a buffer with a couple of intermediate steps...
// CGImageRef -> CFDataRef -> byte array
CGImageRef cgImage = CGBitmapContextCreateImage(context);
CGDataProviderRef provider = CGImageGetDataProvider(cgImage);
CFDataRef pixelData = CGDataProviderCopyData(provider);
// cleanup:
CGColorSpaceRelease(colorSpace);
CGImageRelease(cgImage);
CGContextRelease(context);
const UInt8* data = CFDataGetBytePtr(pixelData);
// we got all the data we need.
// bytes in the data buffer are a succession of R G B A bytes
CGFloat y = 100 * point.y / imageHeight;
int pixelIndex = (int)y * 4; // 4 bytes per color
UIColor *color = [UIColor colorWithRed:data[pixelIndex + 0]/255.0f
green:data[pixelIndex + 1]/255.0f
blue:data[pixelIndex + 2]/255.0f
alpha:data[pixelIndex + 3]/255.0f];
// done fetching color data, finally release the buffer
CGDataProviderRelease(provider);
return color;
}
1 ответ
Решение
Я проверил ваш код, и проблема, кажется, в том, что нужно сделать немного умножения, чтобы point.y
до расчета pixelIndex
:
CGFloat y = 100 * point.y / imageHeight;
int pixelIndex = (int)y * 4; // 4 bytes per color
Я удалил это из вашего кода, и это работает. Также изменилось point
для int
чтобы соответствовать imageWidth
параметр, и ограничил его, чтобы всегда быть 0 <= point < imageWidth
:
- (UIColor*) getColorForPoint: (NSInteger) point imageWidth: (NSInteger) imageWidth
{
point = MIN(imageWidth - 1, MAX(0, point));
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
// create a gradient
CGPoint startPoint = CGPointMake(0, 0);
CGPoint endPoint = CGPointMake(imageWidth, 0);
// create a bitmap context to draw the gradient to, 1 pixel high.
CGContextRef context = CGBitmapContextCreate(NULL, imageWidth, 1, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);
// draw the gradient into it
CGContextAddRect(context, CGRectMake(0, 0, imageWidth, 1));
CGContextClip(context);
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
// Get our RGB bytes into a buffer with a couple of intermediate steps...
// CGImageRef -> CFDataRef -> byte array
CGImageRef cgImage = CGBitmapContextCreateImage(context);
CGDataProviderRef provider = CGImageGetDataProvider(cgImage);
CFDataRef pixelData = CGDataProviderCopyData(provider);
// cleanup:
CGColorSpaceRelease(colorSpace);
CGImageRelease(cgImage);
CGContextRelease(context);
const UInt8* data = CFDataGetBytePtr(pixelData);
// we got all the data we need.
// bytes in the data buffer are a succession of R G B A bytes
int pixelIndex = (int)point * 4; // 4 bytes per color
UIColor *color = [UIColor colorWithRed:data[pixelIndex + 0]/255.0f
green:data[pixelIndex + 1]/255.0f
blue:data[pixelIndex + 2]/255.0f
alpha:data[pixelIndex + 3]/255.0f];
// done fetching color data, finally release the buffer
CGDataProviderRelease(provider);
return color;
}