图片

图片文件格式


如果你想获取一个数码相机导出的数码相片的EXIF和GPS信息,或者你想保存图片数据为TIFF格式,你可能会用到ImageIO.framework 框架。

图片IO框架引入了一个图片源的概念(CGImageSourceRef)。可以通过一个磁盘上的文件URL或者NSData对象(实际上是CFDataRef,可从NSData转换得到)来创建这个数据源。通过这个数据源,你可以获取原图片的一个CGImage对象(或者是一组CGImage,如果是gif格式)。而且,你还可以从源文件中直接获取元数据(metadata),不需要转换成CGImage,大大地节省内存。例如:

NSURL* url = [[NSBundle mainBundle] URLForResource:@"colson"
                    withExtension:@"jpg"];
CGImageSourceRef src = CGImageSourceCreateWithURL((__bridge CFURLRef)url, nil);
CFDictionaryRef result1 = CGImageSourceCopyPropertiesAtIndex(src, 0, nil);
NSDictionary* result = CFBridgingRelease(result1);
// ... do something with result ...
CFRelease(src);

上面的代码,不需要载入一个图片文件,我们直接获取到包含这个图片文件信息的一个NSDictionary 对象,里面包含了它的分辨率,它颜色模式,它的色彩深度,它的方向,另外,由于这个图片是从一个数码相机导出来的,我们还可以获取到它的EXIF数据,如光圈和采用的曝光值,厂名和相机的型号。

我们可以通过CGImageSourceCreateImageAtIndex 来获取CGImage。我还可以请求这个图片的一个缩略图,如果你只是想展示这个图片时,这是非常有用的。而且你还可以指定这个缩略图的大小。

下面我们创建一个指定大小的缩略图,让缩略图的最大分辨率不超过UIImageView(iv)的宽度,还要根据设备的屏幕考虑合适的缩放:

NSURL* url =
    [[NSBundle mainBundle] URLForResource:@"colson"
                            withExtension:@"jpg"];
CGImageSourceRef src =
    CGImageSourceCreateWithURL((__bridge CFURLRef)url, nil);
CGFloat scale = [UIScreen mainScreen].scale;
CGFloat w = self.iv.bounds.size.width*scale;
NSDictionary* d =
    @{(id)kCGImageSourceShouldAllowFloat: (id)kCFBooleanTrue,
     (id)kCGImageSourceCreateThumbnailWithTransform: (id)kCFBooleanTrue,
     (id)kCGImageSourceCreateThumbnailFromImageAlways: (id)kCFBooleanTrue,
     (id)kCGImageSourceThumbnailMaxPixelSize: @((int)w)};
CGImageRef imref =
    CGImageSourceCreateThumbnailAtIndex(src, 0, (__bridge CFDictionaryRef)d);
UIImage* im =
    [UIImage imageWithCGImage:imref scale:scale
                  orientation:UIImageOrientationUp];
self.iv.image = im;
CFRelease(imref); CFRelease(src);

我们还可以把图片数据保存为指定的格式:

NSURL* url =
    [[NSBundle mainBundle] URLForResource:@"colson"
                            withExtension:@"jpg"];
CGImageSourceRef src =
    CGImageSourceCreateWithURL((__bridge CFURLRef)url, nil);
NSFileManager* fm = [NSFileManager new];
NSURL* suppurl = [fm URLForDirectory:NSApplicationSupportDirectory
                            inDomain:NSUserDomainMask
                   appropriateForURL:nil
                              create:YES error:nil];
NSURL* tiff = [suppurl URLByAppendingPathComponent:@"mytiff.tiff"];
CGImageDestinationRef dest =
    CGImageDestinationCreateWithURL((__bridge CFURLRef)tiff,
                                    (CFStringRef)@"public.tiff", 1, nil);
CGImageDestinationAddImageFromSource(dest, src, 0, nil);
bool ok = CGImageDestinationFinalize(dest);
// error-checking omitted
CFRelease(src); CFRelease(dest);

获取远程图片的大小,类型


有时候,你可能会想在不下载完整的图片前提下,获取远程服务器的图片大小,分辨率,类型等信息,下面推荐两个网址:

http://stackoverflow.com/questions/7164435/remote-image-size-without-downloading http://stackoverflow.com/questions/23609063/get-images-files-dimensions-remotely-through-file-url

它是通过下载前面的几kb图片数据,抽取图片头部信息,进行分析来获得相关的图片信息,不过代码还没有完全支持所有的图片格式。

另外,还有一个开源的Ruby项目,里面也使用了同样的解析方法:

https://github.com/sdsykes/fastimage

posted @ 2014-10-16 16:35  剑尖  阅读(373)  评论(0编辑  收藏  举报