ios 系统相册时加载是原图还是html 缩略图 原图

iOS实现头像选取(照相或者图片库)、大小等比缩放、生成圆形头像
//弹出actionsheet。选择获取头像的方式
//从相册获取图片
-(void)takePictureClick:(UIButton *)sender
/*注:使用,需要实现以下协议:UIImagePickerControllerDelegate,
UINavigationControllerDelegate
UIImagePickerController *picker = [[UIImagePickerController alloc]init];
//设置图片源(相簿)
picker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosA
//设置代理
picker.delegate =
//设置可以编辑
picker.allowsEditing = YES;
//打开拾取器界面
[self presentViewController:picker animated:YES completion:nil];
UIActionSheet* actionSheet = [[UIActionSheet alloc]
initWithTitle:@"请选择文件来源"
delegate:self
cancelButtonTitle:@"取消"
destructiveButtonTitle:nil
otherButtonTitles:@"照相机",@"摄像机",@"本地相簿",@"本地视频",nil];
[actionSheet showInView:self.view];
#pragma mark -
#pragma UIActionSheet Delegate
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
NSLog(@"buttonIndex = [%d]",buttonIndex);
switch (buttonIndex) {
case 0://照相机
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate =
imagePicker.allowsEditing = YES;
imagePicker.sourceType = UIImagePickerControllerSourceTypeC
[self presentModalViewController:imagePicker animated:YES];
[self presentViewController:imagePicker animated:YES completion:nil];
case 1://摄像机
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate =
imagePicker.allowsEditing = YES;
imagePicker.sourceType = UIImagePickerControllerSourceTypeC
imagePicker.videoQuality = UIImagePickerControllerQualityTypeL
[self presentModalViewController:imagePicker animated:YES];
[self presentViewController:imagePicker animated:YES completion:nil];
case 2://本地相簿
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate =
imagePicker.allowsEditing = YES;
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoL
[self presentModalViewController:imagePicker animated:YES];
[self presentViewController:imagePicker animated:YES completion:nil];
case 3://本地视频
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate =
imagePicker.allowsEditing = YES;
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoL
[self presentModalViewController:imagePicker animated:YES];
[self presentViewController:imagePicker animated:YES completion:nil];
#pragma mark -
#pragma UIImagePickerController Delegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
if ([[info objectForKey:UIImagePickerControllerMediaType] isEqualToString:(__bridge NSString *)kUTTypeImage]) {
UIImage *img = [info objectForKey:UIImagePickerControllerEditedImage];
[self performSelector:@selector(saveImage:)
withObject:img afterDelay:0.5];
else if ([[info objectForKey:UIImagePickerControllerMediaType] isEqualToString:(__bridge NSString *)kUTTypeMovie]) {
NSString *videoPath = [[info objectForKey:UIImagePickerControllerMediaURL] path];
self.fileData = [NSData dataWithContentsOfFile:videoPath];
[picker dismissModalViewControllerAnimated:YES];
[picker dismissViewControllerAnimated:YES completion:nil];
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
[picker dismissModalViewControllerAnimated:YES];
[picker dismissViewControllerAnimated:YES completion:nil];
- (void)saveImage:(UIImage *)image {
NSLog(@"保存头像!");
[userPhotoButton setImage:image forState:UIControlStateNormal];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *imageFilePath = [documentsDirectory stringByAppendingPathComponent:@"selfPhoto.jpg"];
NSLog(@"imageFile-&&%@",imageFilePath);
success = [fileManager fileExistsAtPath:imageFilePath];
if(success) {
success = [fileManager removeItemAtPath:imageFilePath error:&error];
UIImage *smallImage=[self scaleFromImage:image toSize:CGSizeMake(80.0f, 80.0f)];//将图片尺寸改为80*80
UIImage *smallImage = [self thumbnailWithImageWithoutScale:image size:CGSizeMake(93, 93)];
[UIImageJPEGRepresentation(smallImage, 1.0f) writeToFile:imageFilePath atomically:YES];//写入文件
UIImage *selfPhoto = [UIImage imageWithContentsOfFile:imageFilePath];//读取图片文件
[userPhotoButton setImage:selfPhoto forState:UIControlStateNormal];
self.img.image = selfP
// 改变图像的尺寸,方便上传服务器
- (UIImage *) scaleFromImage: (UIImage *) image toSize: (CGSize) size
UIGraphicsBeginImageContext(size);
[image drawInRect:CGRectMake(0, 0, size.width, size.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newI
}2.保持原始图片的长宽比,生成需要尺寸的图片//2.保持原来的长宽比,生成一个缩略图
- (UIImage *)thumbnailWithImageWithoutScale:(UIImage *)image size:(CGSize)asize
if (nil == image) {
newimage =
CGSize oldsize = image.
if (asize.width/asize.height & oldsize.width/oldsize.height) {
rect.size.width = asize.height*oldsize.width/oldsize.
rect.size.height = asize.
rect.origin.x = (asize.width - rect.size.width)/2;
rect.origin.y = 0;
rect.size.width = asize.
rect.size.height = asize.width*oldsize.height/oldsize.
rect.origin.x = 0;
rect.origin.y = (asize.height - rect.size.height)/2;
UIGraphicsBeginImageContext(asize);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [[UIColor clearColor] CGColor]);
UIRectFill(CGRectMake(0, 0, asize.width, asize.height));//clear background
[image drawInRect:rect];
newimage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}3.显示圆形头像NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *imageFilePath = [documentsDirectory stringByAppendingPathComponent:@"selfPhoto.jpg"];
NSLog(@"imageFile-&&%@",imageFilePath);
UIImage *selfPhoto = [UIImage imageWithContentsOfFile:imageFilePath];//
self.img.image = selfP
[self.img.layer setCornerRadius:CGRectGetHeight([self.img bounds]) / 2];
//修改半径,实现头像的圆形化
self.img.layer.masksToBounds = YES;示例包下载:如果您查看本文后有所收获,欢迎您永久收藏到自己的账号中,同时也欢迎您分享给您的朋友
相关文章推荐
(Ctrl+Enter提交) &&
已有0人在此发表见解
&在& 21:20收藏到了
版权所有,转载本站文章还请保留本站文章或作者地址。 &&
· 蜀ICP备号-1
点击名称选择存放文件夹苹果园为iOS用户提供和下载,最新的、、、等,分享最权威的资讯、、及解决办法,拥有最火爆的,苹果园一家专注解决iOS所求的网站。6391人阅读
IOS开发(224)
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:696767次
积分:7637
积分:7637
排名:第1670名
原创:79篇
转载:241篇
评论:46条
(1)(3)(6)(5)(14)(2)(2)(9)(4)(1)(4)(3)(1)(7)(8)(6)(2)(6)(18)(20)(10)(9)(6)(17)(15)(7)(40)(16)(9)(18)(40)(12)iOS开发中用imageIO渐进加载图片及获取exif的方法
作者:一片枫叶
字体:[ ] 类型:转载 时间:
这篇文章主要介绍了iOS开发中中用imageIO渐进加载图片及获取exif的方法,代码演示为传统的Objective-C,需要的朋友可以参考下
imageIO完成渐进加载图片
一、常见渐进加载图片模式
  目前我们看到的渐进加载主要有以下三种实现方式:
  1)& 依次从web上加载不同尺寸的图片,从小到大。最开始先拉取一个小缩略图做拉伸显示,然后拉取中等规格的图,拉取完毕直接覆盖显示,最后拉取原图,拉取完成后显示原图。
  2)直接从web上拉取最大的图片,每接受一点儿数据就显示一点儿图片,这样就会实现从上到下一点点刷新出来的效果。
  3)结合第1种和第2种,先拉取一个缩略图做拉伸显示,然后采用第二种方法直接拉取原图,这样即可以实现渐进加载,也可以节省几次中间的网络请求。
二、通过imageIO实现图片的渐进加载
  imageIO的guide中原话是这么说的: "If you have a very large image, or are loading image data over the web, you may want to create an incremental image source so that you can draw the image data as you accumulate it. "
  翻译过来就是: "如果你想加载一副特别大的图片,或者从网络上加载一副图片,你可以通过创建一个imageSource实现渐进加载的效果。"翻译的不是很地道,大概就是这么个意思,以前在做PowerCam的时候,当时为了在iOS上处理超大图的时候也试过这种方法,当时测试使用的是一副中国地图,分辨率为的,结果是当整幅图片加载到内存时,内存吃不消,于是就放弃了。现在想想对于这种超大图片的处理,我们可以采用分片的方式进行,每次只需要处理一小块图片即可,这个问题就留给大家思考吧。
  今天我们要讨论的是CGImageSource实现从web端渐进加载图片,要达到这个目的我们需要创建一个URLConnnection,然后实现代理,每次接收到数据时更新图片即可。下面主要的实现源码:
//& SvIncrementallyImage.m
//& SvIncrementallyImage
//& Created by& maple on 6/27/13.
//& Copyright (c) 2013 maple. All rights reserved.
#import "SvIncrementallyImage.h"
#import &ImageIO/ImageIO.h&
#import &CoreFoundation/CoreFoundation.h&
@interface SvIncrementallyImage () {
&&& NSURLRequest&&& *_
&&& NSURLConnection *_
&&& CGImageSourceRef _incrementallyImgS
&&& NSMutableData&& *_recieveD
&&& long long&&&&&& _expectedL
&&& bool&&&&&&&&&&& _isLoadF
@property (nonatomic, retain) UIImage *
@property (nonatomic, retain) UIImage *thumbI
@implementation SvIncrementallyImage
@synthesize imageURL = _imageURL;
@synthesize image&&& = _
@synthesize thumbImage = _thumbI
- (id)initWithURL:(NSURL *)imageURL
&&& self = [super init];
&&& if (self) {
&&&&&&& _imageURL = [imageURL retain];
&&&&&&& _request = [[NSURLRequest alloc] initWithURL:_imageURL];
&&&&&&& _conn&&& = [[NSURLConnection alloc] initWithRequest:_request delegate:self];
&&&&&&& _incrementallyImgSource = CGImageSourceCreateIncremental(NULL);
&&&&&&& _recieveData = [[NSMutableData alloc] init];
&&&&&&& _isLoadFinished =
#pragma mark -
#pragma mark NSURLConnectionDataDelegate
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
&&& _expectedLeght = response.expectedContentL
&&& NSLog(@"expected Length: %lld", _expectedLeght);
&&& NSString *mimeType = response.MIMET
&&& NSLog(@"MIME TYPE %@", mimeType);
&&& NSArray *arr = [mimeType componentsSeparatedByString:@"/"];
&&& if (arr.count & 1 || ![[arr objectAtIndex:0] isEqual:@"image"]) {
&&&&&&& NSLog(@"not a image url");
&&&&&&& [connection cancel];
&&&&&&& [_conn release]; _conn =
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
&&& NSLog(@"Connection %@ error, error info: %@", connection, error);
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
&&& NSLog(@"Connection Loading Finished!!!");
&&& // if download image data not complete, create final image
&&& if (!_isLoadFinished) {
&&&&&&& CGImageSourceUpdateData(_incrementallyImgSource, (CFDataRef)_recieveData, _isLoadFinished);
&&&&&&& CGImageRef imageRef = CGImageSourceCreateImageAtIndex(_incrementallyImgSource, 0, NULL);
&&&&&&& self.image = [UIImage imageWithCGImage:imageRef];
&&&&&&& CGImageRelease(imageRef);
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
&&& [_recieveData appendData:data];
&&& _isLoadFinished =
&&& if (_expectedLeght == _recieveData.length) {
&&&&&&& _isLoadFinished =
&&& CGImageSourceUpdateData(_incrementallyImgSource, (CFDataRef)_recieveData, _isLoadFinished);
&&& CGImageRef imageRef = CGImageSourceCreateImageAtIndex(_incrementallyImgSource, 0, NULL);
&&& self.image = [UIImage imageWithCGImage:imageRef];
&&& CGImageRelease(imageRef);
  从上面代码中我们可以看到,一开始我们根据传入的URL创建一个URLConnection,同时创建一个空的CGImageSource,然后在每次收到数据的时候调用CGImageSourceUpdateData更新imageSource的数据,接着调用CGImageSourceCreateImageAtIndex获取最新的图片即可。
  怎么样,看到上面的实现是不是感觉实现从web上渐进加载图片很简单,虽然imageIO帮我们做了很多事情,但是我们也应该了解它的原理。我们知道文件都是有格式的,一般文件的头部会记录一些关于文件格式的数据,后面就是实际的文件数据。
  拿最简单的BMP图片文件举例:
  1)& 最开始的BITMAPFILEHEADER,这部分主要记录文件的大小,以及实际的图像数据离文件头的距离。
  2)& 接着是BITMAPINFOHEADER,这部分主要记录图片的宽,高,位深等信息
  3)可选的调色板信息
  4)最后一部分就是实际的图片数据。
  前三部分的信息很小,一般加起来不会超过100个字节,获取到这写信息以后,我们就可以很轻松的根据后面的数据构建出图片,当数据获取的越来越完整的时候,我们构造出的图片就会越完整,直至全部加载完成。
  BMP格式是简单的图片格式,其他的JPG,PNG虽然结果更加复杂,但是总体构成都差不多。imageIO正是帮助我们完成了众多图片格式的编解码,然后一步步构造出最终的图片。
使用imageIO获取图片的exif信息
一幅图片除了包含我们能看见的像素信息,背后还包含了拍摄时间,光圈大小,曝光等信息。UIImage类将这些细节信息都隐藏了起来,只提供我们关心的图片尺寸,图片方向等。我们可以通过imageIO框架获取到图片背后的所有信息,下面就让我们一起看看。
  imageIO框架是iOS中偏底层一点儿的框架,它内部提供的接口都是C风格的,关键数据也都是使用CoreFoundation进行存储。庆幸的是CoreFoundation中有很多数据类型都可以上层的数据Foundation框架中的数据类型进行无缝桥接。这也就大大方便了我们对图片信息的操作。
  CGImageSourceRef是整个imageIO的入口,通过它我们可以完成从文件的加载图片。加载完成以后我们就得到一个CGImageSourceRef,通过CGImageSourceRef我们就可以获取图片文件的大小,UTI(uniform type identifier),内部包含几张图片,访问每一张图片以及获取每张图片对应的exif信息等。
  你可能会有一个疑问,为什么会有几张图片呢?
  这块儿我解释一下,imageSourceRef和文件是一一对应的,通常我们见到的图片文件(例如jpg,png)内部都只有一张图片,这种情况我们通过CGImageSourceGetCount方法得到的就会是1。但是不能排除一个图片文件中会有多种图片的情况,例如gif文件,这个时候一个文件中就可能包含几张甚至几十张图片。前面我写的一片博客《IOS中如何解析并显示Gif》就是通过imageSource实现加载和解析gif的功能。
  下面是系统相机拍的照片的exif信息:
image property: {
&&& ColorModel = RGB;
&&& DPIHeight = 72;
&&& DPIWidth = 72;
&&& Depth = 8;
&&& Orientation = 6;
&&& PixelHeight = 2448;
&&& PixelWidth = 3264;
&&& "{Exif}" =&&&& {
&&&&&&& ApertureValue = "2.526069";
&&&&&&& BrightnessValue = "-0.5140446";
&&&&&&& ColorSpace = 1;
&&&&&&& ComponentsConfiguration =&&&&&&&& (
&&&&&&&&&&& 1,
&&&&&&&&&&& 2,
&&&&&&&&&&& 3,
&&&&&&&&&&& 0
&&&&&&& );
&&&&&&& DateTimeDigitized = " 22:11:30";
&&&&&&& DateTimeOriginal = " 22:11:30";
&&&&&&& ExifVersion =&&&&&&&& (
&&&&&&&&&&& 2,
&&&&&&&&&&& 2,
&&&&&&&&&&& 1
&&&&&&& );
&&&&&&& ExposureMode = 0;
&&&&&&& ExposureProgram = 2;
&&&&&&& ExposureTime = "0.";
&&&&&&& FNumber = "2.4";
&&&&&&& Flash = 16;
&&&&&&& FlashPixVersion =&&&&&&&& (
&&&&&&&&&&& 1,
&&&&&&&&&&& 0
&&&&&&& );
&&&&&&& FocalLenIn35mmFilm = 33;
&&&&&&& FocalLength = "4.13";
&&&&&&& ISOSpeedRatings =&&&&&&&& (
&&&&&&&&&&& 400
&&&&&&& );
&&&&&&& MeteringMode = 3;
&&&&&&& PixelXDimension = 3264;
&&&&&&& PixelYDimension = 2448;
&&&&&&& SceneCaptureType = 0;
&&&&&&& SensingMethod = 2;
&&&&&&& ShutterSpeedValue = "3.906905";
&&&&&&& SubjectArea =&&&&&&&& (
&&&&&&&&&&& 2815,
&&&&&&&&&&& 1187,
&&&&&&&&&&& 610,
&&&&&&&&&&& 612
&&&&&&& );
&&&&&&& WhiteBalance = 0;
&&& "{GPS}" =&&&& {
&&&&&&& Altitude = "27.77328";
&&&&&&& AltitudeRef = 0;
&&&&&&& Latitude = "22.5645";
&&&&&&& LatitudeRef = N;
&&&&&&& Longitude = "113.7";
&&&&&&& LongitudeRef = E;
&&&&&&& TimeStamp = "14:11:23.36";
&&& "{TIFF}" =&&&& {
&&&&&&& DateTime = " 22:11:30";
&&&&&&& Make = A
&&&&&&& Model = "iPhone 5";
&&&&&&& Orientation = 6;
&&&&&&& ResolutionUnit = 2;
&&&&&&& Software = "6.1.4";
&&&&&&& XResolution = 72;
&&&&&&& YResolution = 72;
&&&&&&& "_YCbCrPositioning" = 1;
  从中我们可以看出最开始的几项分别显示了当前图片的颜色模式,色深,x,y方向的DPI,实际像素以及图片的方向。我最开始看到这个方向时,心中一喜这不是UIImage中的imageOrientation,但是实验发现这个方向和UIImage中的imageOrientation并不相等,此处的方向是exif标准定义的方向,从1到8分别对应这UIImage中的8个方向,只是顺序不一样,它们对应关系如下:
&&& exifOrientationUp = 1,&&&&& // UIImageOrientationUp
&&& exifOrientationDown = 3,&&& // UIImageOrientationDown
&&& exifOrientationLeft = 6,&&& // UIImageOrientationLeft
&&& exifOrientationRight = 8,&& // UIImageOrientationRight
&&& // these four exifOrientation does not support by all camera, but IOS support these orientation
&&& exifOrientationUpMirrored = 2,&&&&&&&&& // UIImageOrientationUpMirrored
&&& exifOrientationDownMirrored = 4,&&&&&&& // UIImageOrientationDownMirrored
&&& exifOrientationLeftMirrored = 5,&&&&&&& // UIImageOrientationLeftMirrored
&&& exifOrientationRightMirrored = 7,&&&&&& // UIImageOrientationRightMirrored
typedef NSInteger ExifO
  目前市面上的大部分数码相机和手机都会内置一个方向感应器,拍出的照片中会写如方向信息,但是通常都只会有前四种方向。这几种Mirrored方向通常都是手机前置摄像头自拍的时候才会设置。
  exif为什么要搞这么一个方向呢?
  几乎所有的摄像头在出场的时候成相芯片都是有方向的,拍出来的照片的像素都是默认方向的。如果每拍一张照片就对这些像素进行旋转,如果数码相机每秒连拍20张来算,旋转操作将会非常耗时。更聪明的做法是拍照时只记录一个方向,然后显示的时候按方向显示出来即可。因此exif定义了一个标准的方向参数,只要读图的软件都来遵守规则,加载时候读取图片方向,然后做相应的旋转即可。这样既可以达到快速成像的目的,又能达到正确的显示,何乐而不为呢。
  常见的图片浏览和编辑软件都遵守这个规则,但是有一个我们最常用的看图软件(windows自带的看图程序)不会去读这个方向,因此我们将数码相机和手机拍出来的图片导入windows上时,会经常遇到方向错误的问题。不知道windows帝国是怎么想的,或许和定义exif的组织有什么过节吧。
  图片信息中除了上面看提到的那些,还有拍摄的GPS信息,iOS自带的相册软件中的地点tab就是按照GPS信息实现的。还有很多其他的信息,感兴趣的可以自己写个程序研究研究,这里就不展开了。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具

我要回帖

更多关于 缩略图打开后不是原图 的文章

 

随机推荐