您可以尝试使用CGImageSourceCreateThumbnailAtIndex和CGImageSourceCopyPropertiesAtIndex来调整作为jpeg图像的NSData对象的大小,而不会丢失EXIF。 我的灵感来自Problem setting exif data for an image 下面是我为同样目的编写的代码。 干杯
+ (NSData *)JPEGRepresentationSavedMetadataWithImage:(NSData *)imageData compressionQuality:(CGFloat)compressionQuality maxSize:(CGFloat)maxSize
{
CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL);
CFDictionaryRef options = (__bridge CFDictionaryRef)@{(id)kCGImageSourceCreateThumbnailWithTransform: (id)kCFBooleanTrue,
(id)kCGImageSourceCreateThumbnailFromImageIfAbsent: (id)kCFBooleanTrue,
(id)kCGImageSourceThumbnailMaxPixelSize: [NSNumber numberWithDouble: maxSize], // The maximum width and height in pixels of a thumbnail
(id)kCGImageDestinationLossyCompressionQuality: [NSNumber numberWithDouble:compressionQuality]};
CGImageRef thumbnail = CGImageSourceCreateThumbnailAtIndex(source, 0, options); // Create scaled image
CFStringRef UTI = kUTTypeJPEG;
NSMutableData *destData = [NSMutableData data];
CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)destData, UTI, 1, NULL);
if (!destination) {
NSLog(@"Failed to create image destination");
}
CGImageDestinationAddImage(destination, thumbnail, CGImageSourceCopyPropertiesAtIndex(source, 0, NULL)); // copy all metadata in source to destination
if (!CGImageDestinationFinalize(destination)) {
NSLog(@"Failed to create data from image destination");
}
CFRelease(destination);
CFRelease(source);
CFRelease(thumbnail);
return [destData copy];
}
class func resizeImage(imageData: Data, maxResolution: Int, compression: CGFloat) -> Data? {
// create image source from jpeg data
if let myImageSource = CGImageSourceCreateWithData(imageData as CFData, nil) {
// get source properties so we retain metadata (EXIF) for the downsized image
if var metaData = CGImageSourceCopyPropertiesAtIndex(myImageSource,0, nil) as? [String:Any],
let width = metaData[kCGImagePropertyPixelWidth as String] as? Int, let height = metaData[kCGImagePropertyPixelHeight as String] as? Int {
let srcMaxResolution = max(width, height)
// if max resolution is exceeded, then scale image to new resolution
if srcMaxResolution >= maxResolution {
let scaleOptions = [ kCGImageSourceThumbnailMaxPixelSize as String : maxResolution,
kCGImageSourceCreateThumbnailFromImageAlways as String : true] as [String : Any]
if let scaledImage = CGImageSourceCreateThumbnailAtIndex(myImageSource, 0, scaleOptions as CFDictionary) {
// add compression ratio to desitnation options
metaData[kCGImageDestinationLossyCompressionQuality as String] = compression
//create new jpeg
let newImageData = NSMutableData()
if let cgImageDestination = CGImageDestinationCreateWithData(newImageData, "public.jpeg" as CFString, 1, nil) {
CGImageDestinationAddImage(cgImageDestination, scaledImage, metaData as CFDictionary)
CGImageDestinationFinalize(cgImageDestination)
return newImageData as Data
}
}
}
}
}
return nil
}
}
4条答案
按热度按时间ux6nzvsh1#
您可以尝试使用CGImageSourceCreateThumbnailAtIndex和CGImageSourceCopyPropertiesAtIndex来调整作为jpeg图像的NSData对象的大小,而不会丢失EXIF。
我的灵感来自Problem setting exif data for an image
下面是我为同样目的编写的代码。
干杯
vql8enpb2#
我也遇到了同样的问题,现在我可以上传文件与EXIF数据,也可以压缩照片,如果需要它,这为我解决了问题:
9jyewag03#
支持Greener Chen的答案,但这是我在Swift 3中实现它的方式。
kCGImageDestinationLossyCompressionQuality
到CGImageSourceCreateThumbnailAtIndex()
,这是一个CGImageSource
函数-但从来没有尝试过。kCGImageDestinationLossyCompressionQuality
)作为CGImageDestinationAddImage
的一个选项添加到保留的源元数据集,可将压缩添加到目标映像CGImageDestinationAddImage()
非常聪明,可以忽略任何维度数据(W+H),并自动替换为正确的,调整大小的图像,尺寸。所以PixelHeight
,PixelWidth
(“根”元数据)&PixelXDimension
&PixelYDimension
(EXIF)不会从源中继承,并且会正确设置为调整大小后的图像尺寸。flmtquvp4#
您可以使用ExifTool之类的公用程式来删除并还原EXIF。这是一个跨平台的指令行公用程式。以下是执行您想要的作业的适当指令。
要删除EXIF:
exiftool -exif=图像. jpg
若要在编辑图像后再次恢复EXIF:
exiftool -文件中的标签image.jpg_original -exifimage.jpg
在本例中,我利用了ExifTool自动生成的“_original”备份。