如何使PNG变暗?

时间:2012-03-03 21:36:25

标签: objective-c uiimageview uiimage drawing drawrect

我可能会指出Objective-C中的绘图和渲染是我的弱点。现在,这是我的问题。

我想在游戏中添加“日/夜”功能。它在地图上有很多对象。每个对象都是一个UIView,其中包含变量和一些UIImageViews中的一些数据:精灵,一些对象有一个隐藏的环(用于显示选择)。

我希望能够使UIView的内容变暗,但我无法弄清楚如何。精灵是一个透明的PNG。我刚刚设法在精灵后面添加了一个黑色矩形:

CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSaveGState(ctx);

CGContextSetRGBFillColor(ctx, 0, 0, 0, 0.5);
CGContextFillRect(ctx, rect);
CGContextRestoreGState(ctx);

正如我所读到的,这应该在drawRect方法中完成。求救!

如果你想更好地理解我的场景,我正在尝试这样做的应用程序在App Store中被称为“Kipos”。

4 个答案:

答案 0 :(得分:2)

Floris497的方法是一种很好的策略,可以同时对一个以上的图像进行全面变暗(在这种情况下可能更多是你所追求的)。但这是生成较暗的UIImages(同时尊重alpha像素)的通用方法:

+ (UIImage *)darkenImage:(UIImage *)image toLevel:(CGFloat)level
{
    // Create a temporary view to act as a darkening layer
    CGRect frame = CGRectMake(0.0, 0.0, image.size.width, image.size.height);
    UIView *tempView = [[UIView alloc] initWithFrame:frame];
    tempView.backgroundColor = [UIColor blackColor];
    tempView.alpha = level;

    // Draw the image into a new graphics context
    UIGraphicsBeginImageContext(frame.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    [image drawInRect:frame];

    // Flip the context vertically so we can draw the dark layer via a mask that
    // aligns with the image's alpha pixels (Quartz uses flipped coordinates)
    CGContextTranslateCTM(context, 0, frame.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);
    CGContextClipToMask(context, frame, image.CGImage);
    [tempView.layer renderInContext:context];

    // Produce a new image from this context
    CGImageRef imageRef = CGBitmapContextCreateImage(context);
    UIImage *toReturn = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);
    UIGraphicsEndImageContext();
    [tempView release];
    return toReturn;
}

答案 1 :(得分:1)

最好的方法是将核心图像过滤器添加到使其变暗的图层。您可以使用CIExposureAdjust

CIFilter *filter = [CIFilter filterWithName:@"CIExposureAdjust"];
[filter setDefaults];
[filter setValue:[NSNumber numberWithFloat:-2.0] forKey:@"inputEV"];
view.layer.filters = [NSArray arrayWithObject:filter];

答案 2 :(得分:1)

以下是如何操作:

// inputEV controlls the exposure, the lower the darker (e.g "-1" -> dark) 
-(UIImage*)adjustImage:(UIImage*)image exposure:(float)inputEV
{
    CIImage *inputImage = [[CIImage alloc] initWithCGImage:[image CGImage]];
    UIImageOrientation originalOrientation = image.imageOrientation;

    CIFilter* adjustmentFilter = [CIFilter filterWithName:@"CIExposureAdjust"];
    [adjustmentFilter setDefaults];
    [adjustmentFilter setValue:inputImage forKey:@"inputImage"];
    [adjustmentFilter setValue:[NSNumber numberWithFloat:-1.0] forKey:@"inputEV"];

    CIImage *outputImage = [adjustmentFilter valueForKey:@"outputImage"];
    CIContext* context = [CIContext contextWithOptions:nil];
    CGImageRef imgRef = [context createCGImage:outputImage fromRect:outputImage.extent] ;

    UIImage* img = [[UIImage alloc] initWithCGImage:imgRef scale:1.0 orientation:originalOrientation];

    CGImageRelease(imgRef);

    return img;    
}

记得导入:

#import <QuartzCore/Quartzcore.h>

CoreGraphicsCoreImage框架添加到您的项目中。 使用iOS 5.1在iPhone 3GS上测试 从iOS 5.0开始提供CIFilter

答案 3 :(得分:0)

在其上绘制UIView(黑色)并将“启用用户交互”设置为NO

希望你能用这个做点什么。

然后用它来使它变暗

[UIView animateWithDuration:2
                      animations:^{nightView.alpha = 0.4;}
                          completion:^(BOOL finished){ NSLog(@"done making it dark"); ]; }];

让它变得轻盈

[UIView animateWithDuration:2
                      animations:^{nightView.alpha = 0.0;}
                          completion:^(BOOL finished){ NSLog(@"done making it light again"); ]; }];