IOS实现UIImage倒影的三种方法

实现一
使用一个继承自UIView的类来包含要实现倒影效果的图片,重写这个UIView子类的绘图方法,以实现图片于倒影,
然后把这个View 添加到相应的地方显示。
代码:
CKReflectionImage.h
[cpp]  
#import <UIKit/UIKit.h>  
  
@interface CKReflectionImage : UIView {  
@private  
      
    UIImage *image_;  
      
    /** 
     * Value of gradient start. This value is divided to height of image. 
     */  
    CGFloat visibleReflectionHeight_;  
      
    /** 
     * Padding to top image. 
     */  
    CGFloat paddingToTopImage_;  
}  
  
  
@property (nonatomic, readwrite, retain) UIImage *image;  
@property (nonatomic, readwrite, assign) CGFloat visibleReflectionHeight;  
@property (nonatomic, readwrite, assign) CGFloat paddingToTopImage;  
  
@end  
CKReflectionImage.h
[cpp 
#import "CKReflectionImage.h"  
  
@implementation CKReflectionImage  
  
#pragma mark -  
#pragma mark Properties  
  
@synthesize image = image_;  
@synthesize visibleReflectionHeight = visibleReflectionHeight_;  
@synthesize paddingToTopImage = paddingToTopImage_;  
  
#pragma mark -  
#pragma mark Memory management  
  
- (void)dealloc {  
      
    [image_ release];  
    image_ = nil;  
      
    visibleReflectionHeight_ = 0.0f;  
      
    paddingToTopImage_ = 0.0f;  
      
    [super dealloc];  
      
}  
  
#pragma mark -  
#pragma mark Draw methods  
  
/** 
 * Draws the receiver’s image within the passed-in rectangle. 
 *  
 * @param rect: The portion of the view’s bounds that needs to be updated. 
 */  
- (void)drawRect:(CGRect)rect {  
      
    [super drawRect:rect];  
      
    if (image_ != nil) {  
          
        // Get current context to draw.  
        CGContextRef context = UIGraphicsGetCurrentContext();  
          
        // Reflection image references  
        CGImageRef reflectionImage = NULL;  
        CGImageRef gradientImage = NULL;  
          
        // Frame of image  
        CGRect frame = [self frame];  
        frame.origin.x = 0.0f;  
        frame.origin.y = 0.0f;  
        frame.size.width = CGRectGetWidth(frame);  
        frame.size.height = image_.size.height * CGRectGetWidth(frame) / image_.size.width;  
          
        // Draw initial image in context  
        CGContextSaveGState(context);  
        {  
              
            // Draw image in context, commented but the image show in reverse.  
//            CGContextDrawImage(context, frame, [image_ CGImage]);  
              
            // Push context to draw image.  
            UIGraphicsPushContext(context);  
              
            // Draw original image in top  
            [image_ drawInRect:frame];  
              
            // Pop to context  
            UIGraphicsPopContext();  
              
        }  
        CGContextRestoreGState(context);  
          
        // Create gradient bitmap  
        CGContextSaveGState(context);  
        {  
              
            // Gradient is always black-white and the mask must be in the gray colorspace.  
            CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();  
              
            // Create a bitmap context  
            CGContextRef gradientContext = CGBitmapContextCreate(NULL, CGRectGetWidth(frame), CGRectGetHeight(frame), 8, 0, colorSpace, kCGImageAlphaNone);  
              
            // Define the start and the end grayscale values (with the alpha, even though our  
            // bitmap context doesn't support alpha gradient requieres it).  
            CGFloat colors[] = {0.0f, 1.0f, 1.0f, 1.0f};  
              
            // Creates the CGGradient  
            CGGradientRef grayScaleGradient = CGGradientCreateWithColorComponents(colorSpace, colors, NULL, 2);  
              
            // Release colorSpace reference  
            CGColorSpaceRelease(colorSpace);  
              
            // Create the start and end points for the gradient vector (straight down).  
            CGPoint gradientStartPoint = CGPointMake(0, (CGRectGetHeight(frame) - visibleReflectionHeight_));  
            CGPoint gradientEndPoint = CGPointMake(0, ((CGRectGetHeight(frame) * 2) - visibleReflectionHeight_));  
              
            // Draw gradient into gradient context.  
            CGContextDrawLinearGradient(gradientContext, grayScaleGradient, gradientStartPoint, gradientEndPoint, kCGGradientDrawsAfterEndLocation);  
              
            // Release Gradient reference.  
            CGGradientRelease(grayScaleGradient);  
              
            // Convert the gradient context to image.  
            gradientImage = CGBitmapContextCreateImage(gradientContext);  
              
            // Release gradient context  
            CGContextRelease(gradientContext);  
              
        }  
        CGContextRestoreGState(context);  
          
        // Apply gradient bitmap to new context that contains image.  
        CGContextSaveGState(context);  
        {  
              
            // Create a RGB color space  
            CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();  
              
            // Create bitmap context to join image and gradient context.  
            CGContextRef reflectionContext = CGBitmapContextCreate(NULL, CGRectGetWidth(frame), CGRectGetHeight(frame), 8, 0, colorSpace, (kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast));  
              
            // Release color space  
            CGColorSpaceRelease(colorSpace);  
              
            // First clip mask to context  
            CGContextSaveGState(context);  
            {  
                  
                // Clip gradient mask to reflection context.  
                CGContextClipToMask(reflectionContext, frame, gradientImage);  
                  
            }  
            CGContextRestoreGState(context);  
              
            // Second draw image to context  
            CGContextSaveGState(reflectionContext);  
            {  
                  
                // Push context to draw image.  
                UIGraphicsPushContext(reflectionContext);  
                  
                // Draw original image in top  
                [image_ drawInRect:frame];  
                  
                // Pop to context  
                UIGraphicsPopContext();  
                  
            }  
            CGContextRestoreGState(reflectionContext);  
              
            // Delete gradient image mask  
            CGImageRelease(gradientImage);  
              
            // Convert reflection context to image.  
            reflectionImage = CGBitmapContextCreateImage(reflectionContext);  
              
            // Release reflection context  
            CGContextRelease(reflectionContext);  
              
        }  
        CGContextRestoreGState(context);  
          
        // Transform matrix and draw reflection bitmap.  
        CGContextSaveGState(context);  
        {  
              
            // Translate context matrix to height * 2 but next scale and sum 1.0f of image and padding.  
            CGContextTranslateCTM(context, CGRectGetMinX(frame), (CGRectGetHeight(frame) * 2) + paddingToTopImage_);  
              
            // Flip vertical image in context.  
            CGContextScaleCTM(context, 1.0f, -1.0f);  
              
            // Draw reflection image in context.  
            CGContextDrawImage(context, frame, reflectionImage);  
              
            // Release reflectio image.  
            CGImageRelease(reflectionImage);  
              
        }  
        CGContextRestoreGState(context);  
          
    }  
      
}  
  
/** 
 * Set current image to another image. 
 * 
 * @param image: Another image to set. 
 */  
- (void)setImage:(UIImage *)image {  
      
    if (image_ != image) {  
          
        [image_ release];  
        image_ = [image retain];  
          
    }  
      
    [self setNeedsDisplay];  
      
}  
  
/** 
 * Set current visibleReflectioHeight_ value to another. 
 * 
 * @param gradientStart: Another value to visible reflectio height variable. 
 */  
- (void)setVisibleReflectionHeight:(CGFloat)visibleReflectioHeight {  
      
    if (visibleReflectionHeight_ != visibleReflectioHeight) {  
          
        visibleReflectionHeight_ = visibleReflectioHeight;  
          
    }  
      
    [self setNeedsDisplay];  
      
}  
  
/** 
 * Set current paddingToTopImage variable to another value. 
 * 
 * @param paddingToTopImage: Another value to padding to top image. 
 */  
- (void)setPaddingToTopImage:(CGFloat)paddingToTopImage {  
      
    if (paddingToTopImage_ != paddingToTopImage) {  
          
        paddingToTopImage_ = paddingToTopImage;  
          
    }  
      
    [self setNeedsDisplay];  
      
}  
  
@end  
使用:
[cpp]  
CKReflectionImage *reflectionImage = [[CKReflectionImage alloc] initWithFrame:CGRectMake(96, 20, 128, 460)];  
  
[reflectionImage setBackgroundColor:[UIColor clearColor]];  
  
//set the padding of top image and its reflected image  
[reflectionImage setPaddingToTopImage:5.0f];  
  
// Hide 1/4 parts of image. show 3/4  
[reflectionImage setVisibleReflectionHeight:(CGRectGetWidth([reflectionImage frame]) / 4 * 3)];  
  
[reflectionImage setImage:[UIImage imageNamed:@"1.png"]];  
  
[[self view] addSubview:reflectionImage];  
实现效果
 
实现二
为UIImage添加一个关于倒影的category,以实现返回这个图片,
[cpp]  
#import <UIKit/UIKit.h>  
  
  
@interface UIImage (Reflection)  
  
- (UIImage *)reflectionWithHeight:(int)height;  
- (UIImage *)reflectionWithAlpha:(float)pcnt;  
- (UIImage *)reflectionRotatedWithAlpha:(float)pcnt;  
  
@end  
UIImage+Reflection.h
[cpp] 
#import "UIImage+Reflection.h"  
  
#ifndef UIImageReflectionMethods  
#define UIImageReflectionMethods  
  
CGImageRef CreateGradientImage (int pixelsWide, int pixelsHigh, CGFloat endPoint) {  
    CGImageRef theCGImage = NULL;  
      
    // gradient is always black-white and the mask must be in the gray colorspace  
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();  
      
    // create the bitmap context  
    CGContextRef gradientBitmapContext = CGBitmapContextCreate(NULL, pixelsWide, pixelsHigh, 8, 0, colorSpace, kCGImageAlphaNone);  
      
    // define the start and end grayscale values (with the alpha, even though  
    // our bitmap context doesn't support alpha the gradient requires it)  
    CGFloat colors[] = {0.0, 1.0, 1, 1.0};  
      
    // create the CGGradient and then release the gray color space  
    CGGradientRef grayScaleGradient = CGGradientCreateWithColorComponents(colorSpace, colors, NULL, 2);  
    CGColorSpaceRelease(colorSpace);  
      
    // create the start and end points for the gradient vector (straight down)  
    CGPoint gradientStartPoint = CGPointZero;  
    CGPoint gradientEndPoint = CGPointMake(0, endPoint);  
      
    if (endPoint < 0) {  
        gradientEndPoint = CGPointMake(0, -endPoint);  
    }  
      
    // draw the gradient into the gray bitmap context  
    CGContextDrawLinearGradient(gradientBitmapContext, grayScaleGradient, gradientStartPoint, gradientEndPoint, kCGGradientDrawsAfterEndLocation);  
    CGGradientRelease(grayScaleGradient);  
      
    // convert the context into a CGImageRef and release the context  
    theCGImage = CGBitmapContextCreateImage(gradientBitmapContext);  
      
    if (endPoint < 0) {  
        // rotate  
        CGContextClearRect(gradientBitmapContext, CGRectMake(0, 0, pixelsWide, pixelsHigh));  
        CGContextTranslateCTM(gradientBitmapContext, 0.0, pixelsHigh);  
        CGContextScaleCTM(gradientBitmapContext, 1.0, -1.0);  
        CGContextDrawImage(gradientBitmapContext, CGRectMake(0, 0, pixelsWide, pixelsHigh), theCGImage);  
        CGImageRelease(theCGImage);  
        theCGImage = CGBitmapContextCreateImage(gradientBitmapContext);  
    }  
      
    CGContextRelease(gradientBitmapContext);  
      
    // return the imageref containing the gradient  
    return theCGImage;  
}  
  
static CGContextRef MyCreateBitmapContext (int pixelsWide, int pixelsHigh) {  
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();  
      
    // create the bitmap context  
    CGContextRef bitmapContext = CGBitmapContextCreate (NULL, pixelsWide, pixelsHigh, 8, 0, colorSpace, (kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst));  
    CGColorSpaceRelease(colorSpace);  
      
    return bitmapContext;  
}  
  
#endif  
  
@implementation UIImage (Reflection)  
  
- (UIImage *)reflectionRotatedWithAlpha:(float)pcnt {  
    int height = self.size.height;  
    UIImage * fromImage = self;  
    pcnt = 1.0 / pcnt;  
      
    // create a bitmap graphics context the size of the image  
    CGContextRef mainViewContentContext = MyCreateBitmapContext(fromImage.size.width, height);  
      
    // create a 2 bit CGImage containing a gradient that will be used for masking the   
    // main view content to create the 'fade' of the reflection.  The CGImageCreateWithMask  
    // function will stretch the bitmap image as required, so we can create a 1 pixel wide gradient  
    CGImageRef gradientMaskImage = CreateGradientImage(1, height, -(height * pcnt));  
      
    // create an image by masking the bitmap of the mainView content with the gradient view  
    // then release the  pre-masked content bitmap and the gradient bitmap  
    CGContextClipToMask(mainViewContentContext, CGRectMake(0.0, 0.0, fromImage.size.width, height), gradientMaskImage);  
    CGImageRelease(gradientMaskImage);  
      
    // In order to grab the part of the image that we want to render, we move the context origin to the  
    // height of the image that we want to capture, then we flip the context so that the image draws upside down.  
    // CGContextTranslateCTM(mainViewContentContext, 0.0, height);  
    // CGContextScaleCTM(mainViewContentContext, 1.0, -1.0);  
      
    // draw the image into the bitmap context  
    CGContextDrawImage(mainViewContentContext, CGRectMake(0, 0, fromImage.size.width, fromImage.size.height), [fromImage CGImage]);  
      
    // create CGImageRef of the main view bitmap content, and then release that bitmap context  
    CGImageRef reflectionImage = CGBitmapContextCreateImage(mainViewContentContext);  
    CGContextRelease(mainViewContentContext);  
      
    // convert the finished reflection image to a UIImage   
    UIImage * theImage = [UIImage imageWithCGImage:reflectionImage];  
    // image is retained by the property setting above, so we can release the original  
    CGImageRelease(reflectionImage);  
      
    return theImage;  
}  
  
- (UIImage *)reflectionWithHeight:(int)height {  
    if (height == -1) {  
        height = [self size].height;  
    }  
    if (height == 0)  
        return nil;  
      
    UIImage * fromImage = self;  
      
    // create a bitmap graphics context the size of the image  
    CGContextRef mainViewContentContext = MyCreateBitmapContext(fromImage.size.width, fromImage.size.height);  
      
    // create a 2 bit CGImage containing a gradient that will be used for masking the   
    // main view content to create the 'fade' of the reflection.  The CGImageCreateWithMask  
    // function will stretch the bitmap image as required, so we can create a 1 pixel wide gradient  
    CGImageRef gradientMaskImage = CreateGradientImage(1, height, height);  
      
    // create an image by masking the bitmap of the mainView content with the gradient view  
    // then release the  pre-masked content bitmap and the gradient bitmap  
    CGContextClipToMask(mainViewContentContext, CGRectMake(0.0, 0.0, fromImage.size.width, height), gradientMaskImage);  
    CGImageRelease(gradientMaskImage);  
      
    // In order to grab the part of the image that we want to render, we move the context origin to the  
    // height of the image that we want to capture, then we flip the context so that the image draws upside down.  
    CGContextTranslateCTM(mainViewContentContext, 0.0, fromImage.size.height);  
    CGContextScaleCTM(mainViewContentContext, 1.0, -1.0);  
      
    // draw the image into the bitmap context  
    CGContextDrawImage(mainViewContentContext, CGRectMake(0, 0, fromImage.size.width, fromImage.size.height), [fromImage CGImage]);  
      
    // create CGImageRef of the main view bitmap content, and then release that bitmap context  
    CGImageRef reflectionImage = CGBitmapContextCreateImage(mainViewContentContext);  
    CGContextRelease(mainViewContentContext);  
      
    // convert the finished reflection image to a UIImage   
    UIImage * theImage = [UIImage imageWithCGImage:reflectionImage];  
    // image is retained by the property setting above, so we can release the original  
    CGImageRelease(reflectionImage);  
      
    return theImage;  
}  
  
- (UIImage *)reflectionWithAlpha:(float)pcnt {  
    int height = self.size.height;  
    UIImage * fromImage = self;  
    pcnt = 1.0 / pcnt;  
      
    // create a bitmap graphics context the size of the image  
    CGContextRef mainViewContentContext = MyCreateBitmapContext(fromImage.size.width, height);  
      
    // create a 2 bit CGImage containing a gradient that will be used for masking the   
    // main view content to create the 'fade' of the reflection.  The CGImageCreateWithMask  
    // function will stretch the bitmap image as required, so we can create a 1 pixel wide gradient  
    CGImageRef gradientMaskImage = CreateGradientImage(1, height, height * pcnt);  
      
    // create an image by masking the bitmap of the mainView content with the gradient view  
    // then release the  pre-masked content bitmap and the gradient bitmap  
    CGContextClipToMask(mainViewContentContext, CGRectMake(0.0, 0.0, fromImage.size.width, height), gradientMaskImage);  
    CGImageRelease(gradientMaskImage);  
      
    // In order to grab the part of the image that we want to render, we move the context origin to the  
    // height of the image that we want to capture, then we flip the context so that the image draws upside down.  
    CGContextTranslateCTM(mainViewContentContext, 0.0, height);  
    CGContextScaleCTM(mainViewContentContext, 1.0, -1.0);  
      
    // draw the image into the bitmap context  
    CGContextDrawImage(mainViewContentContext, CGRectMake(0, 0, fromImage.size.width, fromImage.size.height), [fromImage CGImage]);  
      
    // create CGImageRef of the main view bitmap content, and then release that bitmap context  
    CGImageRef reflectionImage = CGBitmapContextCreateImage(mainViewContentContext);  
    CGContextRelease(mainViewContentContext);  
      
    // convert the finished reflection image to a UIImage   
    UIImage * theImage = [UIImage imageWithCGImage:reflectionImage];  
    // image is retained by the property setting above, so we can release the original  
    CGImageRelease(reflectionImage);  
      
    return theImage;  
}  
  
@end  
 
使用非常简单:
[cpp]  
[refView setImage:[image reflectionWithAlpha:0.5]];  
[imageView setImage:[image reflectionWithHeight:50]];  
[topRefView setImage:[image reflectionRotatedWithAlpha:0.5]];  
效果




第三种:通过CAlayer来处理
- (void)viewDidLoad  
{  
  1.     [super viewDidLoad];  
  2.   
  3.       
  4.     [[[self view] layer] setBackgroundColor:[[UIColor blackColor] CGColor]];   
  5.       
  6.     UIImage *balloon = [UIImage imageNamed:@"1.png"];                       //改一下图片名就行了  
  7.       
  8.     CALayer *topLayer = [[CALayer alloc] init];   
  9.       
  10.     [topLayer setBounds:CGRectMake(0.0f, 0.0f, 320.0, 240)];   
  11.       
  12.     [topLayer setPosition:CGPointMake(160.0f, 120.0f)];   
  13.       
  14.     [topLayer setContents:(id)[balloon CGImage]];  
  15.       
  16.     [[[self view] layer] addSublayer:topLayer];  
  17.       
  18.     CALayer *reflectionLayer = [[CALayer alloc] init];   
  19.       
  20.     [reflectionLayer setBounds:CGRectMake(0.0f, 0.0f, 320.0, 240.0)];   
  21.       
  22.     [reflectionLayer setPosition:CGPointMake(160.0f, 310.0f)];  
  23.       
  24.     [reflectionLayer setContents:[topLayer contents]];  
  25.       
  26.     [reflectionLayer setValue:[NSNumber numberWithFloat:180.0] forKeyPath:@"transform.rotation.x"];  
  27.       
  28.     CAGradientLayer *gradientLayer = [[CAGradientLayer alloc] init];   
  29.       
  30.     [gradientLayer setBounds:[reflectionLayer bounds]];   
  31.       
  32.     [gradientLayer setPosition:CGPointMake([reflectionLayer bounds].size.width/2, [reflectionLayer bounds].size.height/2)];  
  33.       
  34.     [gradientLayer setColors:[NSArray arrayWithObjects: (id)[[UIColor clearColor] CGColor],(id)[[UIColor blackColor] CGColor], nil]];  
  35.       
  36.     [gradientLayer setStartPoint:CGPointMake(0.5,0.35)];   
  37.       
  38.     [gradientLayer setEndPoint:CGPointMake(0.5,1.0)];  
  39.       
  40.     [reflectionLayer setMask:gradientLayer];  
  41.       
  42.     [[[self view] layer] addSublayer:reflectionLayer];  
  43.     // Do any additional setup after loading the view, typically from a nib.  
  44. }  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值