在ios中获取矩形像素的最有效方法是什么?

时间:2013-03-31 16:45:19

标签: ios uiimage pixel

我有以下代码试图测试像素矩形中的每个像素

px,py =触摸的位置
dx,dy =要测试的矩形的大小

UIImage *myImage; // image from which pixels are read
int ux = px + dx;
int uy = py + dy;
for (int x = (px-dx); x <= ux; ++x)
{
    for (int y = (py-dy); y <= uy; ++y)
    {
        unsigned char pixelData[] = { 0, 0, 0, 0 };
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        CGContextRef context = CGBitmapContextCreate(pixelData, 1, 1, 8, 4, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
        CGImageRef cgimage = myImage.CGImage;
        int imageWidth = CGImageGetWidth(cgimage);
        int imageHeight = CGImageGetHeight(cgimage);
        CGContextDrawImage(context, CGRectMake(-px, py - imageHeight, imageWidth, imageHeight), cgimage);
        CGColorSpaceRelease(colorSpace);
        CGContextRelease(context);

        // Here I have latest pixel, with RBG values stored in pixelData that I can test
    }
}

内循环中的代码抓取位置x,y处的像素。是否有更有效的方法从UIImage(myImage)中抓取(x-dx,y-dy),(x + dx,y + dy)的整个像素矩形?

1 个答案:

答案 0 :(得分:1)

哇,你的回答很简单。

问题是您要为扫描的每个像素创建一个全新的位图上下文。仅创建一个位图上下文是昂贵的,连续数千次这样做对于性能来说真的很糟糕。

首先创建一个位图上下文(使用自定义数据对象),然后扫描该数据。它会更快。

UIImage *myImage; // image from which pixels are read
CGSize imageSize = [myImage size];    

NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * imageSize.width;
NSUInteger bitsPerComponent = 8;

unsigned char *pixelData = (unsigned char*) calloc(imageSize.height * imageSize.width * bytesPerPixel, sizeof(unsigned char))
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(pixelData, imageSize.width, 1imageSize.height bitsPerComponent, bytesPerPixel, colorSpace, kCGImageAlphaPremultipliedLast);
CGContextDrawImage(context, CGRectMake(0, 0, imageSize.width, imageSize.height), myImage.CGImage);

// you can tweak these 2 for-loops to get whichever section of pixels from the image you want for reading.

for (NSInteger x = 0; x < imageSize.width; x++) {

  for (NSInteger y = 0; y < imageSize.height; y++) {

       int pixelIndex = (bytesPerRow * yy) + xx * bytesPerPixel;

       CGFloat red   = (pixelData[pixelIndex]     * 1.0) / 255.0;
       CGFloat green = (pixelData[pixelIndex + 1] * 1.0) / 255.0;
       CGFloat blue  = (pixelData[pixelIndex + 2] * 1.0) / 255.0;
       CGFloat alpha = (pixelData[pixelIndex + 3] * 1.0) / 255.0;
       pixelIndex += 4;

       UIColor *yourPixelColor = [UIColor colorWithRed:red green:green blue:blue alpha:alpha];

    }
  }
}

// be a good memory citizen
CGColorSpaceRelease(colorSpace);
CGContextRelease(context);
free(pixelData);