图片压缩问题
来源:互联网 发布:虚拟机ubuntu无法联网 编辑:程序博客网 时间:2024/05/22 02:30
最近做论坛功能,发帖的时候需要用到从相册中选取图片然后上传,由于每次上传图片的最大数量为9张,所以需要对图片进行压缩。开始时用了以前经常用的压缩的方法:
[objc] view plain copy
//压缩图片质量
+(UIImage *)reduceImage:(UIImage *)image percent:(float)percent
{
NSData *imageData = UIImageJPEGRepresentation(image, percent);
UIImage *newImage = [UIImage imageWithData:imageData];
return newImage;
}
//压缩成指定大小
+ (UIImage*)imageWithImageSimple:(UIImage*)image scaledToSize:(CGSize)newSize
{
// Create a graphics image context
UIGraphicsBeginImageContext(newSize);
// new size
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
// Get the new image from the context
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
// End the context
UIGraphicsEndImageContext();
// Return the new image.
return newImage;
}
//等比压缩
- (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize
{
UIImage *sourceImage = self;
UIImage *newImage = nil;
CGSize imageSize = sourceImage.size;
CGFloat width = imageSize.width;
CGFloat height = imageSize.height;
CGFloat targetWidth = targetSize.width;
CGFloat targetHeight = targetSize.height;
CGFloat scaleFactor = 0.0;
CGFloat scaledWidth = targetWidth;
CGFloat scaledHeight = targetHeight;
CGPoint thumbnailPoint = CGPointMake(0.0,0.0);
if (CGSizeEqualToSize(imageSize, targetSize) ==NO)
{
CGFloat widthFactor = targetWidth / width;
CGFloat heightFactor = targetHeight / height;
if (widthFactor > heightFactor)
scaleFactor = widthFactor; // scale to fit height
else
scaleFactor = heightFactor; // scale to fit width
scaledWidth = width * scaleFactor;
scaledHeight = height * scaleFactor;
// center the image
if (widthFactor > heightFactor)
{
thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
}
else
if (widthFactor < heightFactor)
{
thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
}
}
UIGraphicsBeginImageContext(targetSize); // this will crop
CGRect thumbnailRect = CGRectZero;
thumbnailRect.origin = thumbnailPoint;
thumbnailRect.size.width = scaledWidth;
thumbnailRect.size.height = scaledHeight;
[sourceImage drawInRect:thumbnailRect];
newImage = UIGraphicsGetImageFromCurrentImageContext();
if(newImage ==nil)
NSLog(@"could not scale image");
//pop the context to get back to the default
UIGraphicsEndImageContext();
return newImage;
}
@end
上面的方法比较常见,可是需要加载到内存中来处理图片,当图片数量多了的时候就会收到内存警告,程序崩溃。研究半天终于在一篇博客中找到了解决方法:
[objc] view plain copy
static size_t getAssetBytesCallback(voidvoid *info, voidvoid *buffer, off_t position, size_t count) {
ALAssetRepresentation *rep = (__bridgeid)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.
NDDebug(@"thumbnailForAsset:maxPixelSize: got an error reading an asset: %@", error);
}
return countRead;
}
static void releaseAssetCallback(voidvoid *info) {
// The info here is an ALAssetRepresentation which we CFRetain in thumbnailForAsset:maxPixelSize:.
// This release balances that retain.
CFRelease(info);
}
// Returns a UIImage for the given asset, with size length at most the passed size.
// The resulting UIImage will be already rotated to UIImageOrientationUp, so its CGImageRef
// can be used directly without additional rotation handling.
// This is done synchronously, so you should call this method on a background queue/thread.
- (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((voidvoid *)CFBridgingRetain(rep), [rep size], &callbacks);
CGImageSourceRef source = CGImageSourceCreateWithDataProvider(provider,NULL);
CGImageRef imageRef = CGImageSourceCreateThumbnailAtIndex(source,0, (__bridge CFDictionaryRef)@{
(NSString *)kCGImageSourceCreateThumbnailFromImageAlways :@YES,
(NSString *)kCGImageSourceThumbnailMaxPixelSize : [NSNumber numberWithInt:size],
(NSString *)kCGImageSourceCreateThumbnailWithTransform :@YES,
});
CFRelease(source);
CFRelease(provider);
if (!imageRef) {
returnnil;
}
UIImage *toReturn = [UIImage imageWithCGImage:imageRef];
CFRelease(imageRef);
return toReturn;
}
采用上面的方法之后内存占用率很低!
- 图片压缩问题
- Android图片压缩问题
- android图片压缩问题
- 图片压缩问题
- 图片压缩问题
- Android图片压缩相关问题
- Android 图片压缩上传问题.
- android 图片压缩奇葩问题
- 关于图片压缩上传问题;
- Android详解图片压缩问题
- 解决java 图片压缩图片图片变色问题
- 求助:PHP图片压缩的问题
- android压缩图片 遇到的问题
- thinkphp上传图片自动压缩问题
- thinkphp上传图片自动压缩问题
- 关于nsdata的压缩的问题base64,图片转字符串,图片的压缩的问题
- android选取本地图片及关于图片压缩上传问题
- 使用Java上传图片经过压缩处理图片变色问题
- OpenCV3速查手册2:CMake编译OpenCV源代码
- php实现搜索提示功能
- 图解微信小程序的项目文件
- 关于C++ map容器的使用和pair类型及函数
- Mac下Android Studio git使用test失败
- 图片压缩问题
- 程序猿的工作和生活,你真的不懂
- Reveal2调试别人App的界面
- 二叉树学习(四):线索二叉树
- iOS资源大全整理
- 静态导入、增强for循环
- C++ 关于“不允许使用数据成员初始值设定”的问题
- 复制构造函数
- struct class