前段时间我使用以下方法从32x32大小的图像中提取像素亮度值数组。如果可能的话,我想将这些值转换回32x32 png图像(图像是黑白的,因此每个像素的红绿色和蓝色值应该相等)。
这是我使用的原始方法:
- (NSArray *)arrayOfPixelBrightnessFromImage:(UIImage *)image {
NSMutableArray *pixelBrightnesses = [[NSMutableArray alloc] init];
CGImageRef inputCGImage = [image CGImage];
NSUInteger width = CGImageGetWidth(inputCGImage);
NSUInteger height = CGImageGetHeight(inputCGImage);
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
UInt32 * pixels;
pixels = (UInt32 *) calloc(height * width, sizeof(UInt32));
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(pixels, width, height,
bitsPerComponent, bytesPerRow, colorSpace,
kCGImageAlphaPremultipliedLast|kCGBitmapByteOrder32Big);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), inputCGImage);
CGColorSpaceRelease(colorSpace);
CGContextRelease(context);
#define Mask8(x) ( (x) & 0xFF )
#define R(x) ( Mask8(x) )
#define G(x) ( Mask8(x >> 8 ) )
#define B(x) ( Mask8(x >> 16) )
UInt32 * currentPixel = pixels;
for (NSUInteger j = 0; j < height; j++) {
for (NSUInteger i = 0; i < width; i++) {
UInt32 color = *currentPixel;
[pixelBrightnesses addObject:@(((R(color)+G(color)+B(color))/3.0)/255.0)];
currentPixel++;
}
}
free(pixels);
#undef R
#undef G
#undef B
return pixelBrightnesses;
}
我真的不是Core Graphics的专家,但是如果有人能帮助我那就太棒了。
P.S。以下是包含像素亮度值的NSArray
示例(应该有1024个项目[32 x 32]):
@[@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@0.8588235294117647,@0.8784313725490196,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@0.8862745098039215,@0.3176470588235294,@0.2588235294117647,@0.592156862745098,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@0.8235294117647058,@0.1882352941176471,@0.5843137254901961,@0.9803921568627451,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@0.7529411764705882,@0.1725490196078431,@0.6862745098039216,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@0.5725490196078431,@0.1843137254901961,@0.7607843137254902,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@0.8588235294117647,@0.3176470588235294,@0.3137254901960784,@0.8862745098039215,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@0.984313725490196,@0.5607843137254902,@0.196078431372549,@0.592156862745098,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@0.7686274509803922,@0.2666666666666667,@0.3568627450980392,@0.8745098039215686,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@0.9176470588235294,@0.4274509803921568,@0.2274509803921569,@0.6901960784313725,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@0.7294117647058823,@0.2235294117647059,@0.4941176470588236,@0.9529411764705882,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@0.9647058823529412,@0.1294117647058824,@0.5803921568627451,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@0.9921568627450981,@0.615686274509804,@0.2901960784313726,@0.2745098039215687,@0.4509803921568628,@0.7058823529411765,@0.9098039215686274,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@0.9921568627450981,@0.8313725490196079,@0.5882352941176471,@0.3529411764705883,@0.2509803921568627,@0.3058823529411765,@0.4549019607843137,@0.6470588235294118,@0.8274509803921568,@0.9568627450980393,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@0.9450980392156862,@0.792156862745098,@0.6,@0.4117647058823529,@0.2862745098039216,@0.2549019607843137,@0.3294117647058823,@0.4666666666666667,@0.6313725490196078,@0.8470588235294118,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@0.9098039215686274,@0.7607843137254902,@0.615686274509804,@0.4549019607843137,@0.1803921568627451,@0.3098039215686275,@0.9686274509803922,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@0.792156862745098,@0.4313725490196079,@0.2313725490196079,@0.4823529411764706,@0.9803921568627451,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@0.9058823529411765,@0.592156862745098,@0.2862745098039216,@0.2901960784313726,@0.6235294117647059,@0.9333333333333333,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@0.9529411764705882,@0.7058823529411765,@0.3843137254901961,@0.2392156862745098,@0.4196078431372549,@0.7725490196078432,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@0.9607843137254902,@0.7333333333333333,@0.4313725490196079,@0.2470588235294118,@0.3372549019607843,@0.6431372549019608,@0.9254901960784314,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@0.9725490196078431,@0.7450980392156863,@0.4392156862745098,@0.2509803921568627,@0.3215686274509804,@0.596078431372549,@0.8784313725490196,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@0.8196078431372549,@0.4862745098039216,@0.2588235294117647,@0.3137254901960784,@0.5882352941176471,@0.8705882352941177,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@0.9215686274509803,@0.6352941176470588,@0.3176470588235294,@0.2627450980392157,@0.5254901960784314,@0.8470588235294118,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@0.9333333333333333,@0.6784313725490196,@0.3803921568627451,@0.2431372549019608,@0.3882352941176471,@0.7254901960784313,@0.9764705882352941,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@0.9882352941176471,@0.7450980392156863,@0.4117647058823529,@0.2431372549019608,@0.3607843137254902,@0.6549019607843137,@0.9176470588235294,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@0.9333333333333333,@0.5882352941176471,@0.2705882352941176,@0.3058823529411765,@0.611764705882353,@0.9019607843137255,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@0.996078431372549,@0.6470588235294118,@0.2235294117647059,@0.407843137254902,@0.788235294117647,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@0.9215686274509803,@0.203921568627451,@0.8156862745098039,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@0.9882352941176471,@0.9058823529411765,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1,@1];
答案 0 :(得分:2)
你只是(基本上)想要反过来。
因此,您需要创建一个新的位图上下文,遍历每个像素,并使用数组中的亮度值填充每个像素(RGB组件都设置为该值)。
这样的事情可以解决问题:
static inline UInt32 colorFromComponents(UInt8* components) {
UInt32 color = 0;
// iterate through components
for (int i = 0; i < 4; i++) {
// shift component by its position
UInt32 component = (UInt32)components[i] << i*8;
// add the component to the color
color += component;
}
return color;
}
...
-(UIImage*) grayscaleImageFromPixelBrightnesses:(NSArray*)brightnesses width:(size_t)width height:(size_t)height bitmapInfo:(CGBitmapInfo)bitmapInfo {
// check that the brightness array has the correct count
if (width*height != brightnesses.count) {
NSLog(@"Pixel brightness array has an incorrect count!");
return nil;
}
// create your data
UInt32* data = calloc(width*height, sizeof(UInt32));
// create a new RGB color space
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
// define your attributes
size_t bytesPerPixel = 4;
size_t bitsPerComponent = 8;
size_t bytesPerRow = bytesPerPixel*width;
// create bitmap context
CGContextRef context = CGBitmapContextCreate(data, width, height, bitsPerComponent, bytesPerRow, colorSpace, bitmapInfo);
// iterate through each pixel
for (NSUInteger i = 0; i < width*height; i++) {
// get the brightness value from the brightness array. round is used due to potential rounding errors from the doubles.
UInt8 brightnessValue = (UInt8)round([(NSNumber*)brightnesses[i] doubleValue]*255.0);
// your color components to write to the pixel
UInt8 components[4] = {brightnessValue, brightnessValue, brightnessValue, 255};
// write components to pixel
data[i] = colorFromComponents(components);
}
// create image from context
CGImageRef img = CGBitmapContextCreateImage(context);
// release data
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
free(data);
// get return image and release CGImage
UIImage* returnImage = [UIImage imageWithCGImage:img];
CGImageRelease(img);
// return image
return returnImage;
}
您还应该删除现有代码中的宏。它们绝对可怕,永远不应该用来代替功能。它们不是类型安全的,可以使调试成为绝对的噩梦。像瘟疫一样避免它们。
我建议你用枚举和类似函数替换你的宏:
enum colorComponent {
redComponent = 0,
greenComponent = 8,
blueComponent = 16,
alphaComponent = 24
};
typedef enum colorComponent colorComponent;
static inline UInt8 getColorComponent(UInt32 color, colorComponent component) {
return (color >> component) & 0xFF;
}
然后您可以像这样使用它:
UInt32 * currentPixel = pixels;
for (NSUInteger j = 0; j < height; j++) {
for (NSUInteger i = 0; i < width; i++) {
UInt32 color = *currentPixel;
[pixelBrightnesses addObject:@(((getColorComponent(color, redComponent)+getColorComponent(color, greenComponent)+getColorComponent(color, blueComponent))/3.0)/255.0)];
currentPixel++;
}
}