将图像转换为偏光滤镜

时间:2011-10-18 05:19:12

标签: objective-c

我试图通过以下方式将图像转换为宝丽来滤镜:

   int m_width = self.size.width;
    int m_height = self.size.height;

    uint32_t *rgbImage = (uint32_t *) malloc(m_width * m_height * sizeof(uint32_t));
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(
                                                 rgbImage,
                                                 m_width,
                                                 m_height,
                                                 8, 
                                                 m_width * 4, 
                                                 colorSpace, 
                                                 kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast
                                                 );
    CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
    CGContextSetShouldAntialias(context, NO);
    CGContextDrawImage(context, CGRectMake(0, 0, m_width, m_height), [self CGImage]);
    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);

    // now convert to grayscale
    uint8_t *m_imageData = (uint8_t *) malloc(m_width * m_height);
    for(int y = 0; y < m_height; y++) 
    {
        for(int x = 0; x < m_width; x++)
        {
            uint32_t rgbPixel=rgbImage[y*m_width+x];
            uint32_t redIn = 0, greenIn = 0,blueIn = 0,max = 0,min = 0,chroma = 0,hue = 0,saturation = 0,redOut = 0,greenOut = 0,blueOut = 0;

            redIn = (rgbPixel>>24)&255;
            greenIn = (rgbPixel>>16)&255;
            blueIn = (rgbPixel>>8)&255;

            //NSLog(@"redIn %u greenIn %u blueIn %u",redIn,greenIn,blueIn);

            max = redIn > greenIn ? redIn > blueIn ? redIn : blueIn : greenIn > blueIn ? greenIn : blueIn;
            min = redIn < greenIn ? redIn < blueIn ? redIn : blueIn : greenIn < blueIn ? greenIn : blueIn;
            chroma = max - min;

            if(chroma != 0)
            {
                if(max == redIn)
                    hue = ((greenIn - blueIn) / chroma) %6 ;
                else if(max == greenIn)
                    hue = ((blueIn - redIn)/chroma) + 2;
                else if(max == blueIn)
                    hue = ((redIn - greenIn)/chroma) + 4;

                hue = (hue+20)%6;

                if(chroma != 0)
                    saturation = chroma / max;

                if(hue >= 0 && hue < 1)
                {
                    redOut = chroma + max - chroma;
                    greenOut = chroma * (1 - abs((hue % 2) - 1)) + max - chroma;
                    blueOut = 0 + max - chroma;
                }
                else if(hue >= 1 && hue < 2)
                {
                    redOut = chroma * (1 - abs((hue % 2) - 1)) + max - chroma;
                    greenOut = chroma + max - chroma;
                    blueOut = 0 + max - chroma;
                }
                else if(hue >= 2 && hue < 3)
                {
                    redOut = 0 + max - chroma;
                    greenOut = chroma + max - chroma;
                    blueOut = chroma * (1 - abs((hue % 2) - 1)) + max - chroma;
                }
                else if(hue >= 3 && hue < 4)
                {
                    redOut = 0 + max - chroma;
                    greenOut = chroma * (1 - abs((hue % 2) - 1)) + max - chroma;
                    blueOut = chroma + max - chroma;
                }
                else if(hue >= 4 && hue < 5)
                {
                    redOut = chroma * (1 - abs((hue % 2) - 1)) + max - chroma;
                    greenOut = 0 + max - chroma;
                    blueOut = chroma + max - chroma;

                }
                else if(hue >= 5 && hue < 6)
                {
                    redOut = chroma + max - chroma;
                    greenOut = 0 + max - chroma;
                    blueOut = chroma * (1 - abs((hue % 2) - 1)) + max - chroma;
                }
            }
            //NSLog(@"redOut %u greenOut %u blueOut %u",redOut,greenOut,blueOut);
            m_imageData[y*m_width+x]=redOut + greenOut + blueOut;
        }
    }
    free(rgbImage);

    // convert from a gray scale image back into a UIImage
    uint8_t *result = (uint8_t *) calloc(m_width * m_height *sizeof(uint32_t), 1);

    // process the image back to rgb
    for(int i = 0; i < m_height * m_width; i++) 
    {
        result[i*4]=0;
        int val=m_imageData[i];
        result[i*4+1]=val;
        result[i*4+2]=val;
        result[i*4+3]=val;
    }
    free(m_imageData);

    // create a UIImage
    colorSpace = CGColorSpaceCreateDeviceRGB();
    context = CGBitmapContextCreate(result, 
                                    m_width, 
                                    m_height, 
                                    8, 
                                    m_width * sizeof(uint32_t), 
                                    colorSpace,
                                    kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast
                                    );
    CGImageRef image = CGBitmapContextCreateImage(context);
    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);
#ifdef kNYXReturnRetainedObjects 
    UIImage* resultUIImage = [[UIImage alloc] initWithCGImage:image];
#else
    UIImage *resultUIImage = [UIImage imageWithCGImage:image];
#endif
    CGImageRelease(image);

    free(result);

    return resultUIImage;

但执行此代码后我没有得到宝丽来图像。 这个代码中的问题是什么,或者你可以用其他方式建议我。

1 个答案:

答案 0 :(得分:0)

代码最明显的问题是,在方法结束时,您创建一个绘图上下文,不对其执行任何操作,然后从中获取图像并将其作为UIImage返回。据推测,这将是空白。我认为您正在尝试获取result中数据中保存的图像 - 我认为您需要查看CGImageCreate而不是设置新的上下文。

有关使用原始数据创建数据提供程序的信息,请参阅here,您需要将其传递给CGImageCreate。这一切看起来都很复杂。