将像素亮度值数组转换回UIImage? [英] Converting Array of Pixel Brightness Values Back into UIImage?

查看:88
本文介绍了将像素亮度值数组转换回UIImage?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

前一段时间,我使用以下方法从32x32尺寸的图像中提取像素亮度值的数组。我想尽可能将这些值转换回32x32 png图像(图像是黑白的,因此每个像素的红色,绿色和蓝色值应该相等)。

A while ago I used the following method to extract an array of pixel brightness values from 32x32 sized images. I'd like to convert these values back into the 32x32 png images if possible (The images were black and white so the red green and blue values should be equal for each pixel).

这是我使用的原始方法:

Here is the original method I used:

- (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的真正专家,但是如果有人可以帮助您对我来说太神奇了。

I'm not really an expert with Core Graphics, but if anyone could help me that would be amazing.

PS以下是 NSArray 包含像素亮度值的示例(应该有1024个项目[32 x 32]):

P.S. Here's an example of the NSArray containing the pixel brightness values (There should be 1024 items [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];


推荐答案

大致相同。



(基本上)您只是想做相反的事情。

In much the same way.

You'll just (basically) want to do the reverse.

所以您要创建一个新的位图上下文,遍历每个像素,并使用阵列中的亮度值填充每个像素(RGB分量均设置为该值)。

So you'll want to create a new bitmap context, iterate through each pixel, and populate each pixel with the brightness value from your array (with the RGB components all set to that value).

应该是这样的做到这一点:

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






Macro Rant ...



您还应该摆脱现有代码中的宏。它们绝对是可怕的,不应代替功能使用。它们的类型不安全,可能会使调试成为绝对的噩梦。


Macro Rant...

You should also get rid of the macros in your existing code. They are absolutely horrible and should never be used instead of a function. They aren't type safe and can make debugging an absolute nightmare. Avoid them like the plague.

我建议您用枚举和类似的函数替换宏:

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

这篇关于将像素亮度值数组转换回UIImage?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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