我在访问相机图像时遇到了一些问题(甚至是来自photalbum的图像)。
调整UIImage
的大小后(我测试了几种不同的调整大小方法,它们都会导致相同的错误)我想访问每个单独的像素,以便移交给复杂的算法。
问题是,当使用CGImageGetDataProvider
- >访问原始像素数据时,通常会有一个bytesPerRow值与图像大小(例如宽度* 4)不匹配。导致EXC_BAD_ACCESS
错误。
也许我们在这里有一个iOS错误...
尽管如此,这是代码:
// UIImage capturedImage from Camera
CGImageRef capturedImageRef = capturedImage.CGImage;
// getting bits per component from capturedImage
size_t bitsPerComponentOfCapturedImage = CGImageGetBitsPerComponent(capturedImageRef);
CGImageAlphaInfo alphaInfoOfCapturedImage = CGImageGetAlphaInfo(capturedImageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
// calculate new size from interface data.
// with respect to aspect ratio
// ...
// newWidth = XYZ;
// newHeight = XYZ;
CGContextRef context = CGBitmapContextCreate(NULL, newWidth, newHeight, bitsPerComponentOfCapturedImage,0 , colorSpace, alphaInfoOfCapturedImage);
// I also tried to make use getBytesPerRow for CGBitmapContextCreate resulting in the same error
// if image was rotated
if(capturedImage.imageOrientation == UIImageOrientationRight) {
CGContextRotateCTM(context, -M_PI_2);
CGContextTranslateCTM(context, -newHeight, 0.0f);
}
// draw on new context with new size
CGContextDrawImage(context, CGRectMake(0, 0, newWidth, newHeight), capturedImage.CGImage);
CGImageRef scaledImage=CGBitmapContextCreateImage(context);
// release
CGColorSpaceRelease(colorSpace);
CGContextRelease(context);
theImage = [UIImage imageWithCGImage: scaledImage];
CGImageRelease(scaledImage);
之后,我想通过
访问缩放图像CGImageRef imageRef = theImage.CGImage;
NSData *data = (NSData *) CGDataProviderCopyData(CGImageGetDataProvider(imageRef));
unsigned char *pixels = (unsigned char *)[data bytes];
// create a new image from the modified pixel data
size_t width = CGImageGetWidth(imageRef);
size_t height = CGImageGetHeight(imageRef);
size_t bitsPerComponent = CGImageGetBitsPerComponent(imageRef);
size_t bitsPerPixel = CGImageGetBitsPerPixel(imageRef);
size_t bytesPerRow = CGImageGetBytesPerRow(imageRef);
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, pixels, [data length], NULL);
NSLog(@"bytesPerRow: %f ", (float)bytesPerRow);
NSLog(@"Image width: %f ", (float)width);
NSLog(@"Image height: %f ", (float)height);
// manipulate the individual pixels
for(int i = 0; i < [data length]; i += 4) {
// accessing (float) pixels[i];
// accessing (float) pixels[i+1];
// accessing (float) pixels[i+2];
}
因此,例如当我使用511x768像素访问图像并将其缩小到290x436时,我得到以下输出:
图片宽度: 290.000000
图片高度:436.000000
bitsPerComponent: 8.000000
bitsPerPixel: 32.000000
bytesPerRow: 1184.000000
你可以清楚地看到bytesPerRow(尽管cocoa自动选择)与<{1}}图像不匹配。
我很乐意看到任何帮助
在width
iOS
SDK 4.3
答案 0 :(得分:1)
您忽略了可能的换行符,因此会收到无效结果。添加以下代码并替换循环;
size_t bytesPerPixel = bitsPerPixel / bitsPerComponent;
//calculate the padding just to see what is happening
size_t padding = bytesPerRow - (width * bytesPerPixel);
size_t offset = 0;
// manipulate the individual pixels
while (offset < [data length])
{
for (size_t x=0; x < width; x += bytesPerPixel)
{
// accessing (float) pixels[offset+x];
// accessing (float) pixels[offset+x+1];
// accessing (float) pixels[offset+x+2];
}
offset += bytesPerRow;
};
附录:行填充的基本推理是优化单个行到32位边界的内存访问。这确实很常见,并且是出于优化目的而做的。