Get RGBA pixel values from UIImage.
来源:互联网 发布:软件开发资源管理 编辑:程序博客网 时间:2024/05/17 04:47
最近有从图片文件里提取像素值的需求,去搜索了一下,大致通过两种方式:(这里仅以PNG图片为例,其它图片格式没有测试过)
1.
- (void)GeneratePixelArray {
UIImage *cImage = [UIImage imageNamed:@"testPNGPiexls-line.PNG"];
int width = (int)cImage.size.width;
int height = (int)cImage.size.height;
unsigned char *cMap = (unsigned char *)malloc(width * height);
memset(cMap, 0, width * height);
CFDataRef imageData = CGDataProviderCopyData(CGImageGetDataProvider(cImage.CGImage));
const UInt32 *pixels = (const UInt32*)CFDataGetBytePtr(imageData);
//0xff 0x00 is guard for this demo
for (int j = 0; j < (width * height); j++)
{
printf("0x%x/n", (unsigned int)pixels[j]);
}
CFRelease(imageData);
}
第一种方法好像有点问题。
2.- (void *)GeneratePixelArray//: (UIImage *) image
{
UIImage *cImage = [[UIImage alloc] imageNamed:@"testPNGPiexls-line.PNG"];
//UIImage *cImage = [UIImage imageNamed:@"ball.png"];
int pixelsWidth = (int)cImage.size.width;
int pixelsHeight = (int)cImage.size.height;
CGRect rect = {{0,0}, {pixelsWidth, pixelsHeight}};
// Use RCG color space without Alpha, just RGB
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
if(colorSpace == NULL)
{
NSLog(@"Error allocating color space! /n");
return NULL;
}
unsigned int bitmapBytesPerRow = pixelsWidth*4;
unsigned int bitmapByteCount = bitmapBytesPerRow*pixelsHeight;
void * bitmapData = malloc(bitmapByteCount);
if (bitmapData == NULL) {
NSLog(@"Memory not allocated!/n");
CGColorSpaceRelease(colorSpace);
return NULL;
}
// create bitmap context ,8 bits per component
CGContextRef context = CGBitmapContextCreate(bitmapData,
pixelsWidth,
pixelsHeight,
8,//bits per component
bitmapBytesPerRow,
colorSpace,
kCGImageAlphaPremultipliedLast);
// Make sure release colorspace before returning
CGColorSpaceRelease(colorSpace);
if (context == NULL)
{
free(bitmapData);
NSLog(@"Context not be created!");
return NULL;
}
// Draw the image to the bitmap context
CGContextDrawImage(context, rect, cImage.CGImage);
// Now we can get a pointer to the image data associated with context
unsigned char *bitsData;
bitsData = CGBitmapContextGetData(context);
if (!bitsData)
{
NSLog(@"Failed");
return;
}
void *data = CGBitmapContextGetData(context);
unsigned char* bitmapData2 = malloc(bitmapByteCount);
if (bitmapData2 == NULL)
{
NSLog(@"Memory not be allocated!/n");
return NULL;
}
unsigned char* rcdata = (unsigned char *)data;
unsigned char* wcdata = bitmapData2;
// remove ARGB's fourth value, it is Alpha
for (int i = 0; i < bitmapByteCount / 4; ++i, rcdata += 4)
{
printf("%x/n", (unsigned int)*(unsigned int*)rcdata);
*(wcdata + 0) = *(rcdata + 0);
*(wcdata + 1) = *(rcdata + 1);
*(wcdata + 2) = *(rcdata + 2);
*(wcdata + 3) = *(rcdata + 3);
if (*(wcdata+3)<20) {
printf("alpha.../n");
}
// if ( (*(wcdata + 0)==255) &&(*(wcdata + 1)==0) && (*(wcdata + 2)==0) ) {
// printf("red/n");
// }
wcdata += 4;// skip alpha
}
CGContextRelease(context);
return bitsData;
}
方法3:
347UIImage → pixelData → UIImage Rountrip
The questions is rather simple: How to manipulate single pixels of an UIImage?
The answer is rather long; but includes a joyful trip into Quartz 2D Graphic land…
// load image, convert to CGImageRef
UIImage *c = [UIImage imageNamed:@"c.png"];
CGImageRef cRef = CGImageRetain(c.CGImage);
// png alpha to mask
NSData* pixelData = (NSData*) CGDataProviderCopyData(CGImageGetDataProvider(cRef));
// image raw data
//NSData* pixelDataRep = UIImagePNGRepresentation(c);
// compressed png data
//NSLog(@"pixelData %i", [pixelData length]);
//NSLog(@"pixelDataRep %i", [pixelDataRep length]);
//NSLog(@"pixelDataRep equal to pixelData: %@", [pixelData isEqualToData:pixelDataRep] ? @"YES" : @"NO");
//UIImage* newImage = [UIImage imageWithData:pixelData];
//[newImage drawInRect:CGRectMake(10, 340, 65, 65)];
//NSLog(@"pixelData %@", pixelData);
unsigned char* pixelBytes = (unsigned char *)[pixelData bytes];
// return pointer to data
// step through char data
for(int i = 0; i < [pixelData length]; i += 4) {
// change accordingly
pixelBytes[i] = pixelBytes[i];
pixelBytes[i+1] = pixelBytes[i+1];
pixelBytes[i+2] = pixelBytes[i+2];
pixelBytes[i+3] = 255;
}
//1ms in Simulator , 5ms on iPhone 3GS , 65x65 pixel
// copy bytes in new NSData
NSData* newPixelData = [NSData dataWithBytes:pixelBytes length:[pixelData length]];
//NSLog(@"newPixelData %@", newPixelData);
//NSLog(@"newPixelData: %@", newPixelData ? @"ok" : @"nil");
//NSLog(@"newPixelData equal to pixelData: %@", [pixelData isEqualToData:newPixelData] ? @"YES" : @"NO");
// cast NSData as CFDataRef
CFDataRef imgData = (CFDataRef)pixelData;
//NSLog(@"CFDataGetLength %i", CFDataGetLength(imgData) );
// Make a data provider from CFData
CGDataProviderRef imgDataProvider = CGDataProviderCreateWithCFData(imgData);
// testing... create data provider from file.... works
//NSString* imageFileName = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"c.png"];
//CGDataProviderRef imgDataProvider = CGDataProviderCreateWithFilename([imageFileName UTF8String]);
// does not work like that
// new image needs to get PNG properties
//CGImageRef throughCGImage = CGImageCreateWithPNGDataProvider(imgDataProvider, NULL, true, kCGRenderingIntentDefault);
// get PNG properties from cRef
size_t width = CGImageGetWidth(cRef);
size_t height = CGImageGetHeight(cRef);
size_t bitsPerComponent = CGImageGetBitsPerComponent(cRef);
size_t bitsPerPixel = CGImageGetBitsPerPixel(cRef);
size_t bytesPerRow = CGImageGetBytesPerRow(cRef);
CGColorSpaceRef colorSpace = CGImageGetColorSpace(cRef);
CGBitmapInfo info = CGImageGetBitmapInfo(cRef);
CGFloat *decode = NULL;
BOOL shouldInteroplate = NO;
CGColorRenderingIntent intent = CGImageGetRenderingIntent(cRef);
// cRef PNG properties + imgDataProvider's data
CGImageRef throughCGImage = CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpace, info, imgDataProvider, decode, shouldInteroplate, intent);
CGDataProviderRelease(imgDataProvider);
//NSLog(@"c %i, throughCGImage: %i", CGImageGetHeight(cRef), CGImageGetHeight(throughCGImage) );
CGImageRelease(throughCGImage);
From: http://www.trembl.org/codec/tag/NSData/
// make UIImage with CGImage
UIImage* newImage = [UIImage imageWithCGImage:throughCGImage];
//NSLog(@"newImage: %@", newImage);
// draw UIImage
[newImage drawInRect:CGRectMake(10, 340, 65, 65)];
示例所有图片如附件,
printf("%x/n", (unsigned int)*(unsigned int*)rcdata); I saved output and method1 & method2 differs!
I'm a beginner.
why? I confused. And metod2 should be right, so what's wrong with method 1.
Thanks!
- Get RGBA pixel values from UIImage.
- UIImage转pixel buffer
- How to get access to edit/get pixel values of Mat in OpenCV
- ios RGBA数据转UIImage
- How to get AVFrame(ffmpeg) from NSImage/UIImage
- Accessing pixel values of Texture2D
- system setting manager, save or get system values from database
- Get Selected Row Values From Kendo Grid On Change Event
- Pixel Aspect Ratio from Wiki
- How to get the Values of Selected Row from a Gridview using ASP.NET
- RobotFramework环境配置二十:数据驱动(Get Sheet Values From Excel)
- get inserted values into...
- OpenCV.2.Computer.Vision.Application.Programming.Cookbook--Accessing pixel values
- RGBA
- RGBA
- RGBA
- RGBA
- Read pixel data from bitmap file
- VC6.0中类存在但class view中不显示
- asp.net 在IIS下操作Excel文件权限不足的解决方法
- Java基础番外篇:自增和自减运算符
- 131
- 对Hibernate 查询结果排序
- Get RGBA pixel values from UIImage.
- Java设计模式—观察者模式(Observer pattern)
- 近期总结(下)
- 网络七层协议
- ubuntu
- ACM做题心得(1)
- poj3370——Halloween treats
- C编程注意事项
- 等待