Simple way to read pixel color values from an PNG

2020-02-17 08:31发布

Is there an easy way to get an two-dimensional array or something similar that represents the pixel data of an image?

I have black & white PNG images and I simply want to read the color value at a certain coordinate. For example the color value at 20/100.

4条回答
爷的心禁止访问
2楼-- · 2020-02-17 08:39

You could put the png into an image view, and then use this method to get the pixel value from a graphics context that you would draw the the image into.

查看更多
何必那么认真
3楼-- · 2020-02-17 08:41

This Category on UIImage might be helpful Source

#import <CoreGraphics/CoreGraphics.h>

#import "UIImage+ColorAtPixel.h"

@implementation UIImage (ColorAtPixel)

- (UIColor *)colorAtPixel:(CGPoint)point {
    // Cancel if point is outside image coordinates
    if (!CGRectContainsPoint(CGRectMake(0.0f, 0.0f, self.size.width, self.size.height), point)) {
        return nil;
    }


    // Create a 1x1 pixel byte array and bitmap context to draw the pixel into.
    // Reference: http://stackoverflow.com/questions/1042830/retrieving-a-pixel-alpha-value-for-a-uiimage
    NSInteger pointX = trunc(point.x);
    NSInteger pointY = trunc(point.y);
    CGImageRef cgImage = self.CGImage;
    NSUInteger width = CGImageGetWidth(cgImage);
    NSUInteger height = CGImageGetHeight(cgImage);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    int bytesPerPixel = 4;
    int bytesPerRow = bytesPerPixel * 1;
    NSUInteger bitsPerComponent = 8;
    unsigned char pixelData[4] = { 0, 0, 0, 0 };
    CGContextRef context = CGBitmapContextCreate(pixelData, 
                                                 1,
                                                 1,
                                                 bitsPerComponent, 
                                                 bytesPerRow, 
                                                 colorSpace,
                                                 kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
    CGColorSpaceRelease(colorSpace);
    CGContextSetBlendMode(context, kCGBlendModeCopy);

    // Draw the pixel we are interested in onto the bitmap context
    CGContextTranslateCTM(context, -pointX, -pointY);
    CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, (CGFloat)width, (CGFloat)height), cgImage);
    CGContextRelease(context);

    // Convert color values [0..255] to floats [0.0..1.0]
    CGFloat red   = (CGFloat)pixelData[0] / 255.0f;
    CGFloat green = (CGFloat)pixelData[1] / 255.0f;
    CGFloat blue  = (CGFloat)pixelData[2] / 255.0f;
    CGFloat alpha = (CGFloat)pixelData[3] / 255.0f;
    return [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
}

@end
查看更多
我想做一个坏孩纸
4楼-- · 2020-02-17 08:45

A class to do it for you, and explained too: http://www.markj.net/iphone-uiimage-pixel-color/

查看更多
放荡不羁爱自由
5楼-- · 2020-02-17 08:50

The direct approach is slightly tedious, but here goes:

  1. Get the CoreGraphics image.

    CGImageRef cgImage = image.CGImage;

  2. Get the "data provider", and from that get the data. NSData * d = [(id)CGDataProviderCopyData(CGImageGetDataProvider(cgImage)) autorelease];

  3. Figure out what format the data is in.

    CGImageGetBitmapInfo();

    CGImageGetBitsPerComponent();

    CGImageGetBitsPerPixel();

    CGImageGetBytesPerRow();

  4. figure out the colour space (PNG supports greyscale/RGB/paletted).

    CGImageGetColorSpace()

The indirect approach is to draw the image to a context (note that you may need to specify the context's byte order if you want any guarantees) and read the bytes out.
If you only want single pixels, it might be faster to draw the image to a 1x1 context with the right rect
(something like (CGRect){{-x,-y},{imgWidth,imgHeight}}).
This will handle colour-space conversion for you. If you just want a brightness value, use a greyscale context.

查看更多
登录 后发表回答