如何在 iPhone 上的图像上获取像素的 RGB 值 [英] How to get the RGB values for a pixel on an image on the iphone

查看:78
本文介绍了如何在 iPhone 上的图像上获取像素的 RGB 值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个 iPhone 应用程序,需要在本质上实现与 photoshop 中的吸管"工具等效的东西,您可以在其中触摸图像上的一个点并捕获相关像素的 RGB 值以确定并匹配其颜色.获取 UIImage 是简单的部分,但是有没有办法将 UIImage 数据转换为位图表示,在其中我可以为给定像素提取此信息?非常感谢提供工作代码示例,并注意我不关心 alpha 值.

I am writing an iPhone application and need to essentially implement something equivalent to the 'eyedropper' tool in photoshop, where you can touch a point on the image and capture the RGB values for the pixel in question to determine and match its color. Getting the UIImage is the easy part, but is there a way to convert the UIImage data into a bitmap representation in which I could extract this information for a given pixel? A working code sample would be most appreciated, and note that I am not concerned with the alpha value.

推荐答案

更多细节...

我今晚早些时候发布了对本页内容的整合和小补充 - 可以在这篇文章的底部找到.但是,我此时正在编辑帖子,以发布我建议的内容(至少对于我的要求,包括修改像素数据)是一种更好的方法,因为它提供了可写数据(而据我了解,提供的方法之前的帖子和这篇帖子的底部提供了对数据的只读参考).

A little more detail...

I posted earlier this evening with a consolidation and small addition to what had been said on this page - that can be found at the bottom of this post. I am editing the post at this point, however, to post what I propose is (at least for my requirements, which include modifying pixel data) a better method, as it provides writable data (whereas, as I understand it, the method provided by previous posts and at the bottom of this post provides a read-only reference to data).

方法一:可写像素信息

  1. 我定义了常量

  1. I defined constants

#define RGBA        4
#define RGBA_8_BIT  8

  • 在我的 UIImage 子类中,我声明了实例变量:

  • In my UIImage subclass I declared instance variables:

    size_t bytesPerRow;
    size_t byteCount;
    size_t pixelCount;
    
    CGContextRef context;
    CGColorSpaceRef colorSpace;
    
    UInt8 *pixelByteData;
    // A pointer to an array of RGBA bytes in memory
    RPVW_RGBAPixel *pixelData;
    

  • 像素结构(在这个版本中带有 alpha)

  • The pixel struct (with alpha in this version)

    typedef struct RGBAPixel {
        byte red;
        byte green;
        byte blue;
        byte alpha;
    } RGBAPixel;
    

  • 位图函数(返回预先计算的 RGBA;将 RGB 除以 A 得到未修改的 RGB):

  • Bitmap function (returns pre-calculated RGBA; divide RGB by A to get unmodified RGB):

    -(RGBAPixel*) bitmap {
        NSLog( @"Returning bitmap representation of UIImage." );
        // 8 bits each of red, green, blue, and alpha.
        [self setBytesPerRow:self.size.width * RGBA];
        [self setByteCount:bytesPerRow * self.size.height];
        [self setPixelCount:self.size.width * self.size.height];
    
        // Create RGB color space
        [self setColorSpace:CGColorSpaceCreateDeviceRGB()];
    
        if (!colorSpace)
        {
            NSLog(@"Error allocating color space.");
            return nil;
        }
    
        [self setPixelData:malloc(byteCount)];
    
        if (!pixelData)
        {
            NSLog(@"Error allocating bitmap memory. Releasing color space.");
            CGColorSpaceRelease(colorSpace);
    
            return nil;
        }
    
        // Create the bitmap context. 
        // Pre-multiplied RGBA, 8-bits per component. 
        // The source image format will be converted to the format specified here by CGBitmapContextCreate.
        [self setContext:CGBitmapContextCreate(
                                               (void*)pixelData,
                                               self.size.width,
                                               self.size.height,
                                               RGBA_8_BIT,
                                               bytesPerRow,
                                               colorSpace,
                                               kCGImageAlphaPremultipliedLast
                                               )];
    
        // Make sure we have our context
        if (!context)   {
            free(pixelData);
            NSLog(@"Context not created!");
        }
    
        // Draw the image to the bitmap context. 
        // The memory allocated for the context for rendering will then contain the raw image pixelData in the specified color space.
        CGRect rect = { { 0 , 0 }, { self.size.width, self.size.height } };
    
        CGContextDrawImage( context, rect, self.CGImage );
    
        // Now we can get a pointer to the image pixelData associated with the bitmap context.
        pixelData = (RGBAPixel*) CGBitmapContextGetData(context);
    
        return pixelData;
    }
    

  • <小时>

    只读数据(以前的信息)- 方法 2:

    <小时>

    步骤 1. 我为字节声明了一个类型:


    Read-Only Data (Previous information) - method 2:


    Step 1. I declared a type for byte:

     typedef unsigned char byte;
    

    第 2 步.我声明了一个结构体来对应一个像素:

    Step 2. I declared a struct to correspond to a pixel:

     typedef struct RGBPixel{
        byte red;
        byte green;
        byte blue;  
        }   
    RGBPixel;
    

    第 3 步.我将 UIImageView 子类化并声明(具有相应的合成属性):

    Step 3. I subclassed UIImageView and declared (with corresponding synthesized properties):

    //  Reference to Quartz CGImage for receiver (self)  
    CFDataRef bitmapData;   
    
    //  Buffer holding raw pixel data copied from Quartz CGImage held in receiver (self)    
    UInt8* pixelByteData;
    
    //  A pointer to the first pixel element in an array    
    RGBPixel* pixelData;
    

    第 4 步.我在名为 bitmap 的方法中放置的子类代码(返回位图像素数据):

    Step 4. Subclass code I put in a method named bitmap (to return the bitmap pixel data):

    //Get the bitmap data from the receiver's CGImage (see UIImage docs)  
    [self setBitmapData: CGDataProviderCopyData(CGImageGetDataProvider([self CGImage]))];
    
    //Create a buffer to store bitmap data (unitialized memory as long as the data)    
    [self setPixelBitData:malloc(CFDataGetLength(bitmapData))];
    
    //Copy image data into allocated buffer    
    CFDataGetBytes(bitmapData,CFRangeMake(0,CFDataGetLength(bitmapData)),pixelByteData);
    
    //Cast a pointer to the first element of pixelByteData    
    //Essentially what we're doing is making a second pointer that divides the byteData's units differently - instead of dividing each unit as 1 byte we will divide each unit as 3 bytes (1 pixel).    
    pixelData = (RGBPixel*) pixelByteData;
    
    //Now you can access pixels by index: pixelData[ index ]    
    NSLog(@"Pixel data one red (%i), green (%i), blue (%i).", pixelData[0].red, pixelData[0].green, pixelData[0].blue);
    
    //You can determine the desired index by multiplying row * column.    
    return pixelData;
    

    第 5 步.我做了一个访问器方法:

    Step 5. I made an accessor method:

    -(RGBPixel*)pixelDataForRow:(int)row column:(int)column{
        //Return a pointer to the pixel data
        return &pixelData[row * column];           
    }
    

    这篇关于如何在 iPhone 上的图像上获取像素的 RGB 值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆