iOS的图片压缩,目前我在用的有两种:
一、在内存中压缩
需要消耗内存,如果图片较多,可能会造成crash
//压缩图片质量
+(UIImage *)reduceImage:(UIImage *)p_w_picpath percent:(float)percent
{
NSData *p_w_picpathData = UIImageJPEGRepresentation(p_w_picpath, percent);
UIImage *newImage = [UIImage p_w_picpathWithData:p_w_picpathData];
return newImage;
}
//压缩图片尺寸
+ (UIImage*)p_w_picpathWithImageSimple:(UIImage*)p_w_picpath scaledToSize:(CGSize)newSize
{
// Create a graphics p_w_picpath context
UIGraphicsBeginImageContext(newSize);
// new size
[p_w_picpath drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
// Get the new p_w_picpath from the context
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
// End the context
UIGraphicsEndImageContext();
// Return the new p_w_picpath.
return newImage;
}
二、利用ALAsset压缩
#import <AssetsLibrary/AssetsLibrary.h>
#import <ImageIO/ImageIO.h>
static size_t getAssetBytesCallback(void *info, void *buffer, off_t position, size_t count) {
ALAssetRepresentation *rep = (__bridge id)info;
NSError *error = nil;
size_t countRead = [rep getBytes:(uint8_t *)buffer fromOffset:position length:count error:&error];
if (countRead == 0 && error) {
// We have no way of passing this info back to the caller, so we log it, at least.
NSLog(@"thumbnailForAsset:maxPixelSize: got an error reading an asset: %@", error);
}
return countRead;
}
static void releaseAssetCallback(void *info) {
// The info here is an ALAssetRepresentation which we CFRetain in thumbnailForAsset:maxPixelSize:.
// This release balances that retain.
CFRelease(info);
}
- (UIImage *)thumbnailForAsset:(ALAsset *)asset maxPixelSize:(NSUInteger)size {
NSParameterAssert(asset != nil);
NSParameterAssert(size > 0);
ALAssetRepresentation *rep = [asset defaultRepresentation];
CGDataProviderDirectCallbacks callbacks = {
.version = 0,
.getBytePointer = NULL,
.releaseBytePointer = NULL,
.getBytesAtPosition = getAssetBytesCallback,
.releaseInfo = releaseAssetCallback,
};
CGDataProviderRef provider = CGDataProviderCreateDirect((void *)CFBridgingRetain(rep), [rep size], &callbacks);
CGImageSourceRef source = CGImageSourceCreateWithDataProvider(provider, NULL);
CGImageRef p_w_picpathRef = CGImageSourceCreateThumbnailAtIndex(source, 0, (__bridge CFDictionaryRef) @{
(NSString *)kCGImageSourceCreateThumbnailFromImageAlways : @YES,
(NSString *)kCGImageSourceThumbnailMaxPixelSize : @(size),
(NSString *)kCGImageSourceCreateThumbnailWithTransform : @YES,
});
CFRelease(source);
CFRelease(provider);
if (!p_w_picpathRef) {
return nil;
}
UIImage *toReturn = [UIImage p_w_picpathWithCGImage:p_w_picpathRef];
CFRelease(p_w_picpathRef);
return toReturn;
}
#pragma mark - UIImagePickerControllerDelegate
- (void)p_w_picpathPickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSLog(@"info:\n%@", info);
UIImage *p_w_picpath = info[UIImagePickerControllerOriginalImage];
NSData *imgData = UIImagePNGRepresentation(p_w_picpath);
NSLog(@"length1: %lu", (unsigned long)imgData.length);
NSURL *p_w_picpathURL = info[UIImagePickerControllerReferenceURL];
ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init];
[assetsLibrary assetForURL:p_w_picpathURL resultBlock:^(ALAsset *asset) {
UIImage *p_w_picpath = [self thumbnailForAsset:asset maxPixelSize:1];
NSData *imgData = UIImagePNGRepresentation(p_w_picpath);
NSLog(@"length2: %lu", (unsigned long)imgData.length);
} failureBlock:nil];
[picker dismissViewControllerAnimated:YES completion:^{
}];
}
使用第二种方法内存占用率很低,很适合做多张图片的压缩处理。
转载于:https://blog.51cto.com/8386217/1641858