iOS:循环图像的像素

Posted

技术标签:

【中文标题】iOS:循环图像的像素【英文标题】:iOS : Looping over the pixels of an Image 【发布时间】:2012-04-11 20:48:45 【问题描述】:

我有两张格式和大小相同的图片。

我想遍历每个图像的像素并找到最左上角和最右下角的差异坐标。

差异被认为是具有相同坐标的两个像素的像素颜色。

您能否提供一个示例代码循环遍历图像像素并获取其颜色值?

【问题讨论】:

【参考方案1】:

这对我有用(这是使用 ARC):

- (BOOL) pointInside: (CGPoint) point withEvent: (UIEvent *) event 
    CGRect r = CGRectZero ;

    r.size =[self size] ;

    CGFloat red ;
    CGFloat green ;
    CGFloat blue ;
    CGFloat alpha ;

    if (point.x < 0 || point.x > r.size.width || point.y < 0 || point.y > r.size.height) 
        return NO ;
    

    [inspector colorAt:point red:&red green:&green blue:&blue alpha:&alpha] ;

    return alpha > 0.01f ;

这就是魔法:)

// CGImageInspection.h
#import <Foundation/Foundation.h>

@interface CGImageInspection : NSObject

+ (CGImageInspection *) imageInspectionWithCGImage: (CGImageRef) imageRef ;

- (void) colorAt: (CGPoint) location
             red: (CGFloat *) red 
           green: (CGFloat *) green
            blue: (CGFloat *) blue
           alpha: (CGFloat *) alpha ;

@end

以及对应的实现:

// CGImageInspection.mm
@interface CGImageInspection ()

- (id) initWithCGImage: (CGImageRef) imageRef ;

@property (assign, nonatomic) CGContextRef  context ;
@property (assign, nonatomic) void *        pixels ;
@property (assign, nonatomic) NSUInteger    bytesPerRow ;
@property (assign, nonatomic) NSUInteger    bytesPerPixel ;

@end

@implementation CGImageInspection

@synthesize context ;
@synthesize pixels ;
@synthesize bytesPerRow ;
@synthesize bytesPerPixel ;

- (void) dealloc 
    if (self.context) 
        ::CGContextRelease(self.context) ;
        self.context = 0 ;
    

    if (self.pixels) 
        ::free(self.pixels) ;
        self.pixels = 0 ;
    

    ::NSLog(@"CGImageInspection going away") ;


+ (CGImageInspection *) imageInspectionWithCGImage: (CGImageRef) imageRef 
    return [[CGImageInspection alloc] initWithCGImage:imageRef] ;


- (id) initWithCGImage: (CGImageRef) imageRef 

    if (self = [super init]) 
        size_t  pixelsWide = ::CGImageGetWidth(imageRef) ;
        size_t  pixelsHigh = ::CGImageGetHeight(imageRef) ;

        self.bytesPerPixel = 4 ;
        self.bytesPerRow = (pixelsWide * self.bytesPerPixel) ;
        int     bitmapByteCount   = (self.bytesPerRow * pixelsHigh) ;

        CGColorSpaceRef colorSpace= ::CGColorSpaceCreateDeviceRGB() ;

        if (colorSpace == 0) 
            return nil ;
        

        self.pixels = ::calloc(bitmapByteCount, 1) ;
        if (self.pixels == 0) 
            ::CGColorSpaceRelease(colorSpace) ;
            return nil ;
        

        self.context = ::CGBitmapContextCreate(
            self.pixels
        ,   pixelsWide
        ,   pixelsHigh
        ,   8      // bits per component
        ,   self.bytesPerRow
        ,   colorSpace
        ,   kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big) ;

        if (self.context == 0) 
            ::free(self.pixels) ;
            self.pixels = 0 ;
            ::CGColorSpaceRelease(colorSpace) ;
            return nil ;
        
        ::CGContextDrawImage(context, (CGRect) 0, 0, pixelsWide, pixelsHigh, imageRef) ;
        ::CGColorSpaceRelease(colorSpace) ;
    

    return self ;



- (void) colorAt: (CGPoint) location
             red: (CGFloat *) red 
           green: (CGFloat *) green
            blue: (CGFloat *) blue
           alpha: (CGFloat *) alpha 

    int yy = (int) location.y ;
    int xx = (int) location.x ;

    int byteIndex = (bytesPerRow * yy) + xx * bytesPerPixel ;
    unsigned char * raw = (unsigned char *) self.pixels ;
    raw += byteIndex ;

    *red    = ((CGFloat) (*raw++)) / 255.0f ;
    *green  = ((CGFloat) (*raw++)) / 255.0f ;
    *blue   = ((CGFloat) (*raw++)) / 255.0f ;
    *alpha  = ((CGFloat) (*raw++)) / 255.0f ;


@end

希望这会有所帮助。

【讨论】:

【参考方案2】:

我认为你被否决了,因为根本不清楚你用谷歌搜索过,不知道,也许你做了,而你的 google-fu 今天不工作。我知道我有过这样的日子!

无论如何,How to get the RGB values for a pixel on an image on the iphone 应该可以帮到你。

【讨论】:

以上是关于iOS:循环图像的像素的主要内容,如果未能解决你的问题,请参考以下文章

PHP - 快速循环图像像素

循环通过图像像素 OpenCV

OpenCV实战——实现高效图像扫描循环

Python和OpenCV创建超快的“for”像素循环

如何循环遍历多点选择的每个点以获取像素值?

向量化代码并从 pytorch 代码中删除嵌套循环