热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ImageIO

ImageIO在阅读有关gif编解码相关的内容时,有见到使用ImageIO相关的内容iOS中ImageIO框架详解与应用分析ImageIOProgrammingG

ImageIO

在阅读有关gif编解码相关的内容时,有见到使用ImageIO相关的内容

  • iOS中ImageIO框架详解与应用分析
  • Image I/O Programming Guide

参考Accessing Image Properties Without Loading the Image Into Memory提到其一些应用

比如说你想获取图片的一些属性,比如图片的尺寸和一些其他的元数据,但是这张图片你并不需要再屏幕上显示。最简单的方式就是使用UIImage:

UIImage *image = [UIImage imageWithContentsOfFile:...];
CGSize imageSize = image.size;
...

这样做所带来的问题是整张图片都会被加载到内存中。由于在内存中是未压缩的,所以一个512 × 512 的图片就有1M

此时就可以使用ImageIO.framework

如下的例子,获取一张网络上的图片,输出图片的大小:

NSString *urlStr = @"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1524748621307&di=46209fd530717b3c1621468c5e22e063&imgtype=0&src=http%3A%2F%2Fa.hiphotos.baidu.com%2Fimage%2Fpic%2Fitem%2F0ff41bd5ad6eddc4c984b29335dbb6fd52663372.jpg";NSURL *imageFileURL = [NSURL URLWithString:urlStr];CGImageSourceRef imageSource = CGImageSourceCreateWithURL((CFURLRef)imageFileURL, NULL);if (imageSource == NULL) {// Error loading imagereturn;}NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:NO], (NSString *)kCGImageSourceShouldCache,nil];CFDictionaryRef imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, (CFDictionaryRef)options);if (imageProperties) {NSNumber *width = (NSNumber *)CFDictionaryGetValue(imageProperties, kCGImagePropertyPixelWidth);NSNumber *height = (NSNumber *)CFDictionaryGetValue(imageProperties, kCGImagePropertyPixelHeight);NSLog(@"Image dimensions: %@ x %@ px", width, height);CFRelease(imageProperties);}CFRelease(imageSource);

输出结果为:

Image dimensions: 1280 x 1920 px

CGImageSourceCopyPropertiesAtIndex()返回的字典包含许多信息

如下可以获取拍摄的日期、相机的模式和GPS信息等:

CFDictionaryRef exif = CFDictionaryGetValue(imageProperties, kCGImagePropertyExifDictionary);if (exif) {NSString *dateTakenString = (NSString *)CFDictionaryGetValue(exif, kCGImagePropertyExifDateTimeOriginal);NSLog(@"Date Taken: %@", dateTakenString);}CFDictionaryRef tiff = CFDictionaryGetValue(imageProperties, kCGImagePropertyTIFFDictionary);if (tiff) {NSString *cameraModel = (NSString *)CFDictionaryGetValue(tiff, kCGImagePropertyTIFFModel);NSLog(@"Camera Model: %@", cameraModel);}CFDictionaryRef gps = CFDictionaryGetValue(imageProperties, kCGImagePropertyGPSDictionary);if (gps) {NSString *latitudeString = (NSString *)CFDictionaryGetValue(gps, kCGImagePropertyGPSLatitude);NSString *latitudeRef = (NSString *)CFDictionaryGetValue(gps, kCGImagePropertyGPSLatitudeRef);NSString *longitudeString = (NSString *)CFDictionaryGetValue(gps, kCGImagePropertyGPSLongitude);NSString *longitudeRef = (NSString *)CFDictionaryGetValue(gps, kCGImagePropertyGPSLongitudeRef);NSLog(@"GPS Coordinates: %@ %@ / %@ %@", longitudeString, longitudeRef, latitudeString, latitudeRef);}

Programming iOS 10 Dive Deep into Views View Controllers and Frameworks一书中,就有这样的使用形式:

let url = Bundle.main.url(forResource:"colson", withExtension: "jpg")!let src = CGImageSourceCreateWithURL(url as CFURL, nil)!let result = CGImageSourceCopyPropertiesAtIndex(src, 0, nil)!let d = result as! [AnyHashable:Any] // :) works because CFString is now AnyHashableprint(d)// just proving it really is a dictionarylet width = d[kCGImagePropertyPixelWidth] as! CGFloatlet height = d[kCGImagePropertyPixelHeight] as! CGFloatprint("\(width) by \(height)")// another way; no one in his right mind would do this, thoughdo {let result = CGImageSourceCopyPropertiesAtIndex(src, 0, nil)!let key = kCGImagePropertyPixelWidth // CFStringlet p1 = Unmanaged.passUnretained(key).toOpaque() // UnsafeMutableRawPointerlet p2 = CFDictionaryGetValue(result, p1) // UnsafeRawPointerlet n = Unmanaged.fromOpaque(p2!).takeUnretainedValue() // CFNumbervar width : CGFloat = 0CFNumberGetValue(n, .cgFloatType, &width) // width is now 640.0print(width)}

缩略图
如果你在显示某个图片的时候,不关心原始的图片数据,缩率图thumbnail正是你所需要的

使用CGImageSourceCreateThumbnailAtIndex时传递一个字典。需要注意的是我们使用的CGImage是实际的像素,所以要考虑到设备的scale

let url = Bundle.main.url(forResource:"colson", withExtension: "jpg")!let src = CGImageSourceCreateWithURL(url as CFURL, nil)!let scale = UIScreen.main.scalelet w = self.iv.bounds.width * scalelet d : [AnyHashable:Any] = [kCGImageSourceShouldAllowFloat : true,kCGImageSourceCreateThumbnailWithTransform : true,kCGImageSourceCreateThumbnailFromImageAlways : true,kCGImageSourceThumbnailMaxPixelSize : w]let imref = CGImageSourceCreateThumbnailAtIndex(src, 0, d as CFDictionary)!let im = UIImage(cgImage: imref, scale: scale, orientation: .up)self.iv.image = imprint(im)print(im.size)

缩略图

保存图片为特定的格式

需要使用到image destination,如下的例子,保存为TIFF

let url = Bundle.main.url(forResource:"colson", withExtension: "jpg")!let src = CGImageSourceCreateWithURL(url as CFURL, nil)!let fm = FileManager.defaultlet suppurl = try! fm.url(for:.applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true)let tiff = suppurl.appendingPathComponent("mytiff.tiff")let dest = CGImageDestinationCreateWithURL(tiff as CFURL, kUTTypeTIFF, 1, nil)!CGImageDestinationAddImageFromSource(dest, src, 0, nil)let ok = CGImageDestinationFinalize(dest)if ok {print("tiff image written to disk")} else {print("something went wrong")}


推荐阅读
author-avatar
平凡小几
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有