objective-c - 检测图像 iOS 中的黑色像素

标签 objective-c ios image colors pixel

截至目前,我正在逐一搜索每个像素,检查颜色并查看它是否为黑色……如果不是,我将继续下一个像素。这需要永远,因为我只能检查大约。每秒 100 像素(加速我的 NSTimer 会卡住应用程序,因为它检查得不够快。)所以无论如何我可以让 Xcode 返回所有黑色像素并忽略其他所有像素所以我只需要检查那些像素而不是每个像素。我正在尝试检测图像最左侧的黑色像素。

这是我当前的代码。

- (void)viewDidLoad {
    timer = [NSTimer scheduledTimerWithTimeInterval: 0.01
                                             target: self
                                           selector:@selector(onTick:)
                                           userInfo: nil repeats:YES];
    y1 = 0;
    x1 = 0;
    initialImage = 0;
    height1 = 0;
    width1 = 0;
}

-(void)onTick:(NSTimer *)timer {
    if (initialImage != 1) {
        /*
        IMAGE INITIALLY GETS SET HERE... "image2.image = [blah blah blah];" took this out for non disclosure reasons
        */
        initialImage = 1;
    }
    //image2 is the image I'm checking the pixels of.
    width1 = (int)image2.size.width;
    height1 = (int)image2.size.height;
    CFDataRef imageData = CGDataProviderCopyData(CGImageGetDataProvider(image2.CGImage));
    const UInt32 *pixels = (const UInt32*)CFDataGetBytePtr(imageData);
    if ( (pixels[(x1+(y1*width1))]) == 0x000000) { //0x000000 is black right?
        NSLog(@"black!");
        NSLog(@"x = %i", x1);
        NSLog(@"y = %i", y1);
    }else {
        NSLog(@"val: %lu", (pixels[(x1+(y1*width1))]));
        NSLog(@"x = %i", x1);
        NSLog(@"y = %i", y1);
        x1 ++;
        if (x1 >= width1) {
            y1 ++;
            x1 = 0;
        }
    }
    if (y1 > height1) {
        /*
        MY UPDATE IMAGE CODE GOES HERE (IMAGE CHANGES EVERY TIME ALL PIXELS HAVE BEEN CHECKED
        */
        y1 = 0;
        x1 = 0;
    }

此外,如果一个像素真的接近黑色但不是完全黑色怎么办...我可以在某处添加误差幅度以便它仍能检测到 95% 黑色的像素吗?谢谢!

最佳答案

你为什么要使用计时器?为什么不在您的函数中使用一个双 for 循环来遍历图像中所有可能的 x 和 y 坐标?当然,这比仅检查每秒最多 100 个像素要快得多。您可能希望在外部循环中使用 x(宽度)坐标,在内部循环中使用 y(高度)坐标,这样您就可以有效地一次从左到右扫描一列像素,因为您正在尝试查找最左边的黑色像素。

此外,您确定图像中的每个像素都有一个 4 字节 (Uint32) 表示吗?标准位图每个像素有 3 个字节。要检查像素是否接近黑色,您只需分别检查像素中的每个字节并确保它们都小于某个阈值。

编辑:好的,因为您使用的是 UIGetScreenImage,所以我假设它是每像素 4 字节。

const UInt8 *pixels = CFDataGetBytePtr(imageData);
UInt8 blackThreshold = 10; // or some value close to 0
int bytesPerPixel = 4;
for(int x = 0; x < width1; x++) {
  for(int y = 0; y < height1; y++) {
    int pixelStartIndex = (x + (y * width1)) * bytesPerPixel;
    UInt8 alphaVal = pixels[pixelStartIndex]; // can probably ignore this value
    UInt8 redVal = pixels[pixelStartIndex + 1];
    UInt8 greenVal = pixels[pixelStartIndex + 2];
    UInt8 blueVal = pixels[pixelStartIndex + 3];
    if(redVal < blackThreshold && blueVal < blackThreshold && greenVal < blackThreshold) {
      //This pixel is close to black...do something with it
    }
  }
}

如果结果 bytesPerPixel 为 3,则相应地更改该值,从 for 循环中删除 alphaVal,并从红色、绿色和蓝色值的索引中减去 1。

另外,我目前的理解是 UIGetScreenImage 被认为是一个私有(private)函数,Apple 可能会也可能不会拒绝您使用它。

关于objective-c - 检测图像 iOS 中的黑色像素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8955110/

相关文章:

ios - 播放完成时快速更改按钮图像

ios - 获取对象 NSDictionary 的键

ios - 覆盖 setContentOffset

ios - 使用 block 的内存泄漏

带有 SLRequest 的 iOS 转发返回错误的 URL 错误

php - 如何上传图片并存入数据库

iOS VIPER : How protocol helps in Unit Testing?

objective-c - 状态项中的默认文本字段

android - 如何在 Android 上显示来自 URL 的图像

android - NavigationDrawer,带有图像的适配器