Objective c 如何使PNG变暗?

Objective c 如何使PNG变暗?,objective-c,uiimageview,uiimage,drawing,drawrect,Objective C,Uiimageview,Uiimage,Drawing,Drawrect,我可以指出,在Objective-C中绘图和渲染是我的弱点。现在,我的问题来了 我想在我的游戏中添加“白天/晚上”功能。地图上有很多物体。每个对象都是一个UIView,包含一些变量中的数据和一些UIImageView:精灵,一些对象有一个隐藏环(用于显示选择) 我希望能够使UIView的内容变暗,但我不知道如何进行。精灵是一个具有透明度的PNG。我刚刚使用以下方法在精灵后面添加了一个黑色矩形: CGContextRef ctx = UIGraphicsGetCurrentContext(); C

我可以指出,在Objective-C中绘图和渲染是我的弱点。现在,我的问题来了

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

我希望能够使UIView的内容变暗,但我不知道如何进行。精灵是一个具有透明度的PNG。我刚刚使用以下方法在精灵后面添加了一个黑色矩形:

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

CGContextSetRGBFillColor(ctx, 0, 0, 0, 0.5);
CGContextFillRect(ctx, rect);
CGContextRestoreGState(ctx);
正如我所读到的,这应该在drawRect方法中完成。救命啊

如果您想更好地理解我的场景,我尝试执行此操作的应用程序在App Store中被称为“Kipos”。

在其上绘制一个UIView(黑色),并将“已启用用户交互”设置为否

希望你能用这个做点什么

然后用这个使它变暗

[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"); ]; }];

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

CIFilter *filter = [CIFilter filterWithName:@"CIExposureAdjust"];
[filter setDefaults];
[filter setValue:[NSNumber numberWithFloat:-2.0] forKey:@"inputEV"];
view.layer.filters = [NSArray arrayWithObject:filter];
以下是如何做到这一点:

// 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>
#导入
并将
CoreGraphics
CoreImage
框架添加到项目中。 在配备iOS 5.1的iPhone 3GS上测试
CIFilter
从iOS 5.0开始提供。

Floris497的方法是一个很好的策略,可以一次对多个图像进行覆盖式暗显(在本例中,可能比您想要的更暗)。但这里有一种通用方法来生成较暗的UIImage(同时考虑alpha像素):


但是图像不是矩形的,它是不规则的,就像一个字符。这将覆盖一个完整的黑色矩形,不是吗?把它放在游戏视图的顶部,它在晚上是半透明的,在白天是完全透明的,所以你看不到它。如果这就是你的意思?嗯,很好。我试试看。将“用户交互”设置为“否”会让触摸通过?是的,因此其背后的一切都将正常工作不要忘记在开始时使视图完全透明。alpha=0;。此解决方案不会使图像变暗,但会使UIImageView变暗。如果你正在寻找一个使图像变暗的代码,请看我的答案。我几乎不了解任何绘图、图层等内容。这将进入drawRect方法?如何添加图层?然后,如何将图像和内容添加到视图中?在设置视图的任何位置(通常在UIViewController中)使用此选项。不过,它确实会减慢视图中的任何动画。它告诉我,它在层中找不到“过滤器”属性。我没有初始化一个层,也没有分配。我应该吗?如果是的话,在哪里?嗯,我以为苹果已经将核心映像移植到iOS,但也许他们没有。那没关系!谢谢你的详细回答!我似乎正是我要找的人!:)我会尝试一下,检查它是否有效/我能够实现它,如果是的话,我会把它标记为正确答案。哇,非常感谢!这些评论真的很有帮助。然后,我将能够调整每个对象的“光”级别,这是我的主要目标。谢谢你,先生!
+ (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;
}