【问题标题】:Converting Array of Pixel Brightness Values Back into UIImage?将像素亮度值数组转换回 UIImage?
【发布时间】:2016-03-27 08:55:46
【问题描述】:

不久前,我使用以下方法从 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 专家,但如果有人能帮助我,那就太棒了。

附:这是一个包含像素亮度值的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];

【问题讨论】:

    标签: ios objective-c uiimage core-graphics


    【解决方案1】:

    以大致相同的方式。

    你只会(基本上)想要做相反的事情。

    因此,您需要创建一个新的位图上下文,遍历每个像素,并使用数组中的亮度值填充每个像素(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++;
        }
    }
    

    【讨论】:

    • 哇,谢谢您的详细回答 originaluser2!!!!对此,我真的非常感激。你对宏是正确的。我肯定会走枚举路线。而且效果很好!以前我得到的结果真的很糟糕。你我的朋友值得奖励!!!
    猜你喜欢
    • 1970-01-01
    • 2016-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多