zoukankan      html  css  js  c++  java
  • How to get the RGB values for a pixel on an image on the iphone

    http://stackoverflow.com/questions/144250/how-to-get-the-rgb-values-for-a-pixel-on-an-image-on-the-iphone

    Method 1: Writable Pixel Information

    I defined constants

    #define RGBA        4
    #define RGBA_8_BIT  8

    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;

    The pixel struct (with alpha in this version)

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

    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;
    }

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

    Step 1. I declared a type for byte:

    typedef unsigned char byte;

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

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

    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;

    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;

    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 ];      
    
    }

    another answer:

    You can't access the bitmap data of a UIImage directly.

    You need to get the CGImage representation of the UIImage. Then get the CGImage's data provider, from that a CFData representation of the bitmap. Make sure to release the CFData when done.

    CGImageRef cgImage = [image CGImage];
    CGDataProviderRef provider = CGImageGetDataProvider(cgImage);
    CFDataRef bitmapData = CGDataProviderCopyData(provider);

    You will probably want to look at the bitmap info of the CGImage to get pixel order, image dimensions, etc.

     To get the pixel data as an array of bytes, I did this:

    UInt8* data = CFDataGetBytePtr(bitmapData);

    More info: CFDataRef documentation.

    Also, remember to include CoreGraphics.framework

  • 相关阅读:
    【转载】USB2.0接口差分信号线设计
    2.4G高频PCB天线设计
    [转]热插拔原理和应用
    [转]or cad drc 错误
    Chrome浏览器任意修改网页内容
    Oracle笔记之约束
    Oracle笔记之表空间
    Oracle笔记之序列(Sequence)
    Oracle笔记之用户管理
    Win7下SQLPlus登录时报错"SP2-1503:无法初始化Oracle调用界面"
  • 原文地址:https://www.cnblogs.com/pengyingh/p/2487590.html
Copyright © 2011-2022 走看看