0

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

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) 中获取整个像素矩形?

4

1 回答 1

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);
于 2013-03-31T18:12:11.710 回答