首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > 移动开发 >

[转载]截取一部分图片并显示

2012-06-29 
[转载]截取部分图片并显示[转自]http://marshal.easymorse.com/archives/3703在ios开发中,肯定会碰到需要

[转载]截取部分图片并显示

[转自]http://marshal.easymorse.com/archives/3703

在ios开发中,肯定会碰到需要截取部分图片的情况。

最终的效果类似这样:

[转载]截取一部分图片并显示[转载]截取一部分图片并显示

先看最原始的示例,显示完整的图片

写了个最简单的读取图片并显示的代码,打算以此为开始,逐渐实现截取部分图片的功能。

代码主要是,在控制器代码中:

- (void)loadView {?
??? [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation: UIStatusBarAnimationSlide];?
??? UIImage *image=[UIImage imageNamed:@"1.jpg"];?
????
??? UIImageView *contentView = [[UIImageView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];?
??? [contentView setImage:image];?
????
??? self.view=[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];?
??? [self.view addSubview:contentView];?
}

另外,应该有一个名为1.jpg的768×1024的图片(我这里是iPad)。

?

?

截取整个图片

可以认为截取整个图片是截取部分图片的一个特例。对ios不熟嘛,因此打算很谨慎的推进。截取整个图片可以减少中间的复杂性。

根据API,摸索着写了一个示例,效果出乎意料:

[转载]截取一部分图片并显示

代码:

- (void)loadView {?
??? [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation: UIStatusBarAnimationSlide];?
??? UIImage *image=[UIImage imageNamed:@"1.jpg"];?
????
??? UIImageView *contentView = [[UIImageView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];?
??? //[contentView setImage:image];?
????
??? CGRect rect = CGRectMake(0, 0, 768, 1024);//创建矩形框?
??? UIGraphicsBeginImageContext(rect.size);//根据size大小创建一个基于位图的图形上下文?
??? CGContextRef currentContext = UIGraphicsGetCurrentContext();//获取当前quartz 2d绘图环境?
??? CGContextClipToRect( currentContext, rect);//设置当前绘图环境到矩形框?
????
??? CGContextDrawImage(currentContext, rect, image.CGImage);//绘图?
??? UIImage *cropped = UIGraphicsGetImageFromCurrentImageContext();//获得图片?
??? UIGraphicsEndImageContext();//从当前堆栈中删除quartz 2d绘图环境?
????
??? contentView.image=cropped;?
????
??? self.view=[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];?
??? [self.view addSubview:contentView];

??? [cropped release];?
}

这个代码说明了两点:

    好的方面:说明我的代码起作用了,确实截取了所需的图形坏的方面:图形是颠倒的,而且是镜像的。

    问题应该出在坐标系上。下面画了一个quartz 2d的坐标系,坐标原点在左下角:

    [转载]截取一部分图片并显示

    因此以这个坐标系取图形,就会有转向180°的效果。

    其实如果是对图片的缩放,而不是剪切部分图片内容,这样写就可以了:

    - (void)loadView {?
    ??? [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation: UIStatusBarAnimationSlide];?
    ??? UIImage *image=[UIImage imageNamed:@"1.jpg"];?
    ????
    ??? //[contentView setImage:image];?
    ????
    ??? CGRect rect = CGRectMake(0, 0, 384, 512);//创建矩形框?
    ??? UIGraphicsBeginImageContext(rect.size);//根据size大小创建一个基于位图的图形上下文?
    ??? CGContextRef currentContext = UIGraphicsGetCurrentContext();//获取当前quartz 2d绘图环境?
    ??? CGContextClipToRect(currentContext, rect);//设置当前绘图环境到矩形框?
    ????
    ??? //CGContextRotateCTM(currentContext, 50);?
    ????
    ??? //CGContextDrawImage(currentContext, rect, image.CGImage);//绘图?
    ????
    ??? [image drawInRect:rect];?
    ????
    ??? UIImage *cropped = UIGraphicsGetImageFromCurrentImageContext();//获得图片?
    ??? UIGraphicsEndImageContext();//从当前堆栈中删除quartz 2d绘图环境?
    ????
    ??? UIImageView *contentView = [[UIImageView alloc] initWithFrame:rect];?
    ??? contentView.image=cropped;?
    ????
    ??? self.view=[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];?
    ??? [self.view addSubview:contentView];

    ??? [cropped release];?
    }

    效果类似这样:

    [转载]截取一部分图片并显示

    这个方法可以帮助我们在后续开发中实现缩略图。但是不符合现在的需求。

    于是想了下面的基本思路:

    [转载]截取一部分图片并显示

    这样,需要一个能旋转和向下移动的API。ios提供了C++界面的函数调用:

      CGContextRotateCTM,实现角度的转换CGContextTranslateCTM,可以重新设置坐标系原点,平移坐标系和移动图片是等效的

      代码:

      - (void)loadView {?
      ??? [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation: UIStatusBarAnimationSlide];?
      ??? UIImage *image=[UIImage imageNamed:@"1.jpg"];?
      ????
      ??? //[contentView setImage:image];?
      ????
      ??? CGRect rect = CGRectMake(0, 0, 384, 512);//创建矩形框?
      ??? UIGraphicsBeginImageContext(rect.size);//根据size大小创建一个基于位图的图形上下文?
      ??? CGContextRef currentContext = UIGraphicsGetCurrentContext();//获取当前quartz 2d绘图环境?
      ??? CGContextClipToRect(currentContext, rect);//设置当前绘图环境到矩形框?
      ????
      ??? CGContextRotateCTM(currentContext, M_PI);?
      ??? CGContextTranslateCTM(currentContext, -rect.size.width, -rect.size.height);?
      ????
      ??? CGContextDrawImage(currentContext, rect, image.CGImage);//绘图?
      ????
      ??? //[image drawInRect:rect];?
      ????
      ??? UIImage *cropped = UIGraphicsGetImageFromCurrentImageContext();//获得图片?
      ??? UIGraphicsEndImageContext();//从当前堆栈中删除quartz 2d绘图环境?
      ????
      ??? UIImageView *contentView = [[UIImageView alloc] initWithFrame:rect];?
      ??? contentView.image=cropped;?
      ????
      ??? self.view=[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];?
      ??? [self.view addSubview:contentView];

      ??? [cropped release];?
      }

      [转载]截取一部分图片并显示

      这个结果还有缺陷,可以看到图片是正立的了,但是图片反转了,是个镜像。

      解决办法也有,不过不是操作图片了,而是操作图片所在的视图。思路是把视图看作一个位图的矩阵,对它做矩阵变换运算,使视图做镜像反转。写法很简单:

      - (void)loadView {?
      ??? [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation: UIStatusBarAnimationSlide];?
      ??? UIImage *image=[UIImage imageNamed:@"1.jpg"];?
      ????
      ??? //[contentView setImage:image];?
      ????
      ??? CGRect rect = CGRectMake(0, 0, 384, 512);//创建矩形框?
      ??? UIGraphicsBeginImageContext(rect.size);//根据size大小创建一个基于位图的图形上下文?
      ??? CGContextRef currentContext = UIGraphicsGetCurrentContext();//获取当前quartz 2d绘图环境?
      ??? CGContextClipToRect(currentContext, rect);//设置当前绘图环境到矩形框?
      ????
      ????
      ??? CGContextRotateCTM(currentContext, M_PI);?
      ??? CGContextTranslateCTM(currentContext, -rect.size.width, -rect.size.height);?
      ??? //CGContextTranslateCTM(currentContext,0.0,200.0);?
      ????
      ??? CGContextDrawImage(currentContext, rect, image.CGImage);//绘图?
      ????
      ??? //[image drawInRect:rect];?
      ????
      ??? UIImage *cropped = UIGraphicsGetImageFromCurrentImageContext();//获得图片?
      ??? UIGraphicsEndImageContext();//从当前堆栈中删除quartz 2d绘图环境?
      ????
      ????????
      ??? UIImageView *contentView = [[UIImageView alloc] initWithFrame:rect];?
      ??? contentView.image=cropped;?
      ????
      ??? contentView.transform = CGAffineTransformIdentity;?
      ??? contentView.transform = CGAffineTransformMakeScale(-1.0, 1.0);

      ????
      ??? self.view=[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];?
      ??? [self.view addSubview:contentView];

      ??? [cropped release];?
      }

      ?

      这里的转换因子,一个是针对x轴的,一个是针对y轴的。终于可以产生这样的效果了:

      [转载]截取一部分图片并显示

      这里参考了这个文档:

      http://macdevcenter.com/pub/a/mac/2004/11/02/quartz.html

      虽然是很古老的文章了,但是说的很清楚。另外,方法名称已经发生变化,需要注意。

      截取部分图片

      截取部分图片,比如:

      [转载]截取一部分图片并显示

      截取左边人像部分。

      实现后的代码,效果是这样的:

      [转载]截取一部分图片并显示

      如何实现的呢,这时候才发现,其实根本不需要上面那些转换,如果不使用quartz 2d的话,截取部分图片这么简单:

      - (void)loadView {?
      ??? [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation: UIStatusBarAnimationSlide];?
      ??? UIImage *image=[UIImage imageNamed:@"1.jpg"];?
      ????
      ????
      ??? CGRect rect = CGRectMake(60, 80, 331, 353);//创建矩形框?
      ??? UIImageView *contentView = [[UIImageView alloc] initWithFrame:rect];?
      ??? contentView.image=[UIImage imageWithCGImage:CGImageCreateWithImageInRect([image CGImage], rect)];?
      ????
      ??? self.view=[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];?
      ??? [self.view addSubview:contentView];?
      ????
      ??? [image release];?
      }

      虽然编写代码的过程是曲折的,但是摸到很多有用的东西,都是以后要用到的。

热点排行