Reputation: 120364
Given a CGRect (rect
) and a UIImage (image
), how do you obtain the alpha values (only) of the image pixels in the rectangle?
The following code always returns 0 alpha, no matter the image or rectangle.
CGContextRef context = CGBitmapContextCreate(NULL,
rect.size.width,
rect.size.height,
8,
rect.size.width,
NULL,
kCGImageAlphaOnly);
UIGraphicsPushContext(context);
[image drawInRect:rect];
char *pixels = CGBitmapContextGetData(context);
NSUInteger pixelCount = rect.size.width * rect.size.height;
for (int i = 0; i < pixelCount; i++)
{
char pixel = pixels[i];
CGFloat alpha = pixel / 255.0;
NSLog(@"%f", alpha);
}
UIGraphicsPopContext();
CGContextRelease(context);
Upvotes: 1
Views: 2180
Reputation: 4389
In Swift 4 the code for getting only the alpha channel would looks like this:
import UIKit
extension UIImage {
func alphaData() -> [UInt8]? {
let size = self.size
var alphaData = [UInt8](repeating: 0, count: Int(size.width) * Int(size.height))
let colorSpace = CGColorSpaceCreateDeviceGray()
let context = CGContext(
data: &alphaData,
width: Int(size.width),
height: Int(size.height),
bitsPerComponent: 8,
bytesPerRow: Int(size.width),
space: colorSpace,
bitmapInfo: CGImageAlphaInfo.alphaOnly.rawValue
);
guard let cgImage = self.cgImage else { return nil }
context?.draw(cgImage, in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
return alphaData
}
}
Upvotes: 2
Reputation: 12717
I think this should help you.. https://github.com/OgreSwamp/ObjFloodFill
Upvotes: 0
Reputation: 8741
In my experience with RGBA values is that they all have to be unsigned char. I am guessing this might have caused your problem since a signed char would stop at 127 and never attain the full 255 value if this image had an opacity of 1 - and possibly worse not being properly aligned (read).
Upvotes: 0
Reputation: 2492
In the past, I have had issues getting CGBitmapContext working properly. I wouldn't be surprised if there was an issue with kCGImageAlphaOnly
. You might do some sanity checking with some of the more 'mainstream' pixel formats like kCGImageAlphaPremultipliedFirst
.
You might also try drawing the image using CGImageDrawImage
:
CGContextRef context = CGBitmapContextCreate(NULL,
rect.size.width,
rect.size.height,
8,
rect.size.width,
NULL,
kCGImageAlphaOnly);
CGContextDrawImage( context, rect, image.CGImage);
//etc...
CGContextRelease(context);
Upvotes: 0
Reputation: 4061
pixelData[index + 3]
will be a value for Alpha. pixelData[0-2]
are RGB respectively
CFDataRef theData;
theData = CGDataProviderCopyData(CGImageGetDataProvider(sourceImage));
CFMutableDataRef mutableData = CFDataCreateMutableCopy(0, 0, theData);
UInt8 *pixelData = (UInt8 *) CFDataGetBytePtr(mutableData);
int dataLength = CFDataGetLength(mutableData);
for (int index = 0; index < dataLength; index += 4) {
//code here for just alpha
pixelData[index + 3]
}
Upvotes: 0