实现一

使用一个继承自UIView的类来包含要实现倒影效果的图片,重写这个UIView子类的绘图方法,以实现图片于倒影,
然后把这个View 添加到相应的地方显示。
代码:

CKReflectionImage.h

#import <UIKit/UIKit.h>@interface CKReflectionImage : UIView {
@privateUIImage *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

#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 referencesCGImageRef reflectionImage = NULL;CGImageRef gradientImage = NULL;// Frame of imageCGRect 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 contextCGContextSaveGState(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 contextUIGraphicsPopContext();}CGContextRestoreGState(context);// Create gradient bitmapCGContextSaveGState(context);{// Gradient is always black-white and the mask must be in the gray colorspace.CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();// Create a bitmap contextCGContextRef 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 CGGradientCGGradientRef grayScaleGradient = CGGradientCreateWithColorComponents(colorSpace, colors, NULL, 2);// Release colorSpace referenceCGColorSpaceRelease(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 contextCGContextRelease(gradientContext);}CGContextRestoreGState(context);// Apply gradient bitmap to new context that contains image.CGContextSaveGState(context);{// Create a RGB color spaceCGColorSpaceRef 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 spaceCGColorSpaceRelease(colorSpace);// First clip mask to contextCGContextSaveGState(context);{// Clip gradient mask to reflection context.CGContextClipToMask(reflectionContext, frame, gradientImage);}CGContextRestoreGState(context);// Second draw image to contextCGContextSaveGState(reflectionContext);{// Push context to draw image.UIGraphicsPushContext(reflectionContext);// Draw original image in top[image_ drawInRect:frame];// Pop to contextUIGraphicsPopContext();}CGContextRestoreGState(reflectionContext);// Delete gradient image maskCGImageRelease(gradientImage);// Convert reflection context to image.reflectionImage = CGBitmapContextCreateImage(reflectionContext);// Release reflection contextCGContextRelease(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

使用:

    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,以实现返回这个图片,
#import <UIKit/UIKit.h>@interface UIImage (Reflection)- (UIImage *)reflectionWithHeight:(int)height;
- (UIImage *)reflectionWithAlpha:(float)pcnt;
- (UIImage *)reflectionRotatedWithAlpha:(float)pcnt;@end

UIImage+Reflection.h

#import "UIImage+Reflection.h"#ifndef UIImageReflectionMethods
#define UIImageReflectionMethodsCGImageRef CreateGradientImage (int pixelsWide, int pixelsHigh, CGFloat endPoint) {CGImageRef theCGImage = NULL;// gradient is always black-white and the mask must be in the gray colorspaceCGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();// create the bitmap contextCGContextRef 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 spaceCGGradientRef 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 contextCGContextDrawLinearGradient(gradientBitmapContext, grayScaleGradient, gradientStartPoint, gradientEndPoint, kCGGradientDrawsAfterEndLocation);CGGradientRelease(grayScaleGradient);// convert the context into a CGImageRef and release the contexttheCGImage = CGBitmapContextCreateImage(gradientBitmapContext);if (endPoint < 0) {// rotateCGContextClearRect(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 gradientreturn theCGImage;
}static CGContextRef MyCreateBitmapContext (int pixelsWide, int pixelsHigh) {CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();// create the bitmap contextCGContextRef 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 imageCGContextRef 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 gradientCGImageRef 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 bitmapCGContextClipToMask(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 contextCGContextDrawImage(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 contextCGImageRef 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 originalCGImageRelease(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 imageCGContextRef 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 gradientCGImageRef 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 bitmapCGContextClipToMask(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 contextCGContextDrawImage(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 contextCGImageRef 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 originalCGImageRelease(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 imageCGContextRef 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 gradientCGImageRef 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 bitmapCGContextClipToMask(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 contextCGContextDrawImage(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 contextCGImageRef 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 originalCGImageRelease(reflectionImage);return theImage;
}@end

使用非常简单:

    [refView setImage:[image reflectionWithAlpha:0.5]];[imageView setImage:[image reflectionWithHeight:50]];[topRefView setImage:[image reflectionRotatedWithAlpha:0.5]];

效果

iOS图片倒影效果的2种实现相关推荐

  1. ios 图片资源管理的四种方式(Assets,bundle文件,Resource,沙盒文件目录下)

    图片资源管理 1. Assets.xcassets 一般是以蓝色的Assets.xcassets的文件夹形式在工程中,以Image Set的形式管理.当一组图片放入的时候同时会生成描述文件Conten ...

  2. iOS之实现图片裁剪的几种方式

    iOS之实现图片裁剪的几种方式 1.使用CGImageCreateWithImageInRect函数 CGImageCreateWithImageInRect函数是属于Core Graphics Fr ...

  3. matlab保存所有图,Matlab中图片保存的5种方法

    matlab的绘图和可视化能力是不用多说的,可以说在业内是家喻户晓的. Matlab提供了丰富的绘图函数,比如ez**系类的简易绘图函数,surf.mesh系类的数值绘图函数等几十个.另外其他专业工具 ...

  4. android 仿照ios 图片选择,GitHub - wildma/PictureSelector: Android 图片选择器(仿 IOS 图片选择控件)...

    PictureSelector Android 图片选择器(仿 IOS 图片选择控件) 效果图 功能特点 支持通过拍照获取图片 支持通过相册获取图片 支持图片是否裁剪两种场景 支持仿 IOS 底部弹出 ...

  5. iOS图片打马赛克的实现方式--------终极解决方案

    iOS图片打马赛克分辨率丢失,图片编辑完成之后保存原图分辨率方案,绘画时内存暴增导致闪退问题 --------终极解决方案 需求是做一个编辑图片功能,结果好不容易各种搜索实现了功能,结果发现一个无解的 ...

  6. ios 图片裁剪框架_iOS图片裁剪器 – RSKImageCropper

    RSKImageCropper iOS图片裁剪器,类似Contacts应用中的图片定位美化. 基础使用方法 导入类header. #import Just create a view controll ...

  7. 分享了iOS获取通讯录的4种方式

    本文实例为大家分享了iOS获取通讯录的4种方式,供大家参考,具体内容如下 使用场景 一些App通过手机号码来推荐好友,如 微博.支付宝 首先客户端会获取通讯录中的所有手机号然后将这些手机号提交到App ...

  8. 大屏iPhone的适配 +iOS 图片尺寸要求

    摘自:http://blog.ibireme.com/2014/09/16/adapted_to_iphone6/ 苹果公司官网设计介绍到:Retina显示屏的超高像素密度已超过人眼能分辨的范围. R ...

  9. ios 图片居中裁剪_iOS 根据UIImage 修改UIImageView Frame (包括截取图片中间部分)...

    iOS UIImageView 根据需求调整frame 1.图片的宽和高不相等,截取图片的中间部分,截取的部分Size明确 2.图片的宽度要等于其父视图的类的宽度,然后根据宽度计算高度,保证 图片不变 ...

最新文章

  1. pytorch nn.LSTM()参数详解
  2. #@python常见的代码自己编写问题
  3. lucene Index Store TermVector 说明
  4. 顶层const和底层const的区别
  5. c语言结构体赋值,并输出各种类型变量的值
  6. 邮件服务器在企业网中的应用
  7. Oracle区分中文和英文,oracle中中英文段落划分实现
  8. redis☞ python客户端
  9. linux设备模型的主要功能,Linux设备模型(3)
  10. 高级转录组分析和R数据可视化第十一期(报名线上课还可免费参加线下课)
  11. c#利用反射+特性实现简单的实体映射数据库操作类(表与类的映射)
  12. Webpack 基础使用
  13. oracle 获取awk报告,Oracle 使用 ass.awk 工具查看 system state dump 说明
  14. 防爆破登录:配置/etc/hosts.deny禁止ip尝试ssh或者telnet操作
  15. 基于Java毕业设计银行贷款管理系统源码+系统+mysql+lw文档+部署软件
  16. 忘记了mysql的root密码(分享:重置密码过程)
  17. SSM车辆维修管理系统毕业设计总结篇
  18. win10下ipv6安装与设置
  19. Back Channel笔记
  20. mybatis plus 代码生成器

热门文章

  1. 子网掩码的计算方法(实例)
  2. Controller传入数组参数
  3. 计算机文档为什么被挂起,win7打印文件桌面右下角显示“文档被挂起”的原因及处理方法...
  4. Web.3空投之王撒福利
  5. Linux笔记:终端复用与管理工具screen和tmux
  6. 2021.11.22-11.28 AI行业周刊(第73期):工作的需求
  7. vue props default Array或是Object的正确写法
  8. 锚点定位——如何设置锚点居页面顶部距离,锚点定位并距离顶部一定偏移
  9. UML 的九种模型图.UML用例图.ER图.UML项目结构图总结
  10. 过度使用耳机会给我们带来多大的危害?选择长期使用的耳机很重要