ionic插件-图片压缩ios端

插件通过传给我们一个图片的绝对路径,让我们进行图片的压缩,从而可以进行上传。

在模拟器上地址格式是这样的:   @"file:///Users/qmc/Library/Developer/CoreSimulator/Devices/B450A007-3FFD-44E2-A893-69B5F94D23A5/data/Containers/Data/Application/0245F4E6-D1E5-42DC-8B60-15519395BAA4/tmp/cdv_photo_026.jpg"    。真机上也是差不多的。但是ios沙盒的路径是不识别这种的,只能是这样的/Users/qmc/...,所以我们首先需要将路径截取成我们需要的。而且需注意的是,该路径存放的是一个tmp文件夹,及临时文件夹,APP退出后里面的文件都会被清空。

fullPath = [fullPath stringByReplacingOccurrencesOfString:@"file://" withString:@""];

获取包换后缀名的文件名以及不不包含文件名的路径

NSString *imageName = [fullPath lastPathComponent];

//    NSString *imagePath = [fullPath stringByReplacingOccurrence sOfString:[@"/" stringByAppendingString:imageName] withString:@""];

- (UIImage *)getPhotoFromName:(NSString *)name filePath:(NSString *)filePath {

//    NSString *tmpDir =  NSTemporaryDirectory();

//    NSString *uniquePath=[[paths objectAtIndex:0] stringByAppendingPathComponent:name];

//    BOOL blHave=[[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"%@%@",tmpDir,name]];

BOOL blHave=[[NSFileManager defaultManager] fileExistsAtPath: filePath];

if (!blHave) {

return nil;

}else

{

NSData *data = [NSData dataWithContentsOfFile:filePath];

UIImage *img = [[UIImage alloc] initWithData:data];

return img;

}}

上面的方法是通过路径及文件名,首先判断该路径下是否有文件,如果存在的话将文件取出给UIImage.返回的UIImage我们就可以操作进行压缩了。

//对图片尺寸进行压缩--

-(UIImage*)imageWithImage:(UIImage*)image scaledToSize:(CGSize)newSize {

// Create a graphics image context

UIGraphicsBeginImageContext(newSize);

// Tell the old image to draw in this new context, with the desired

// 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;}

该方法传入原图片及需求的尺寸,便会返回需求的图片了!

实际原理就是重新给图片绘了一个需求宽高的边。

接下来就是讲图片保存到沙盒中,并且返回一个路径给js。

//保存新的图片 永久保存到沙盒

-(NSString *)saveNewImage:(UIImage *)image WithImageName:(NSString *)imageName{

//xxxx.png

NSString *newName = [imageName stringByReplacingOccurrencesOfString:@".png" withString:@""];

newName = [imageName stringByReplacingOccurrencesOfString:@".jpg" withString:@""];

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);

NSString *filePath = [[paths objectAtIndex:0]stringByAppendingPathComponent:[NSString stringWithFormat:@"%@New.png",newName]];

//校验该文件名是否已经存在

if([[NSFileManager defaultManager] fileExistsAtPath:filePath]){

filePath = [[paths objectAtIndex:0]stringByAppendingPathComponent:[NSString stringWithFormat:@"%@New02.png",newName]];

}

//    UIImageWriteToSavedPhotosAlbum(image, self, nil, NULL);

[UIImagePNGRepresentation(image) writeToFile:filePath atomically:YES];

return filePath;}

可能会出现我们新取得图片名已经有了,这时候做一个判断,如果有相同的名字了就换一个。然后写到document下保存。这种保存的机制是永久的,除非你删掉了APP或者是情空APP数据才会消失。

图片压缩就全部结束了。在做图片压缩耗时最多的就是路径处理那一块。


附代码:

#import "ImageCompress.h"

#import

@implementation ImageCompress

- (NSString *)compress:(CDVInvokedUrlCommand *)command {

NSString *fullPath = command.arguments[0];

fullPath = [fullPath stringByReplacingOccurrencesOfString:@"file://" withString:@""];

NSString *imageName = [fullPath lastPathComponent];

//    NSString *imagePath = [fullPath stringByReplacingOccurrencesOfString:[@"/" stringByAppendingString:imageName] withString:@""];

UIImage *targetImage = [self getPhotoFromName:imageName filePath:fullPath];

UIImage *newImage = [self imageWithImage:targetImage scaledToSize:CGSizeMake(48, 72)];

return [self saveNewImage:newImage WithImageName:imageName];

}

- (UIImage *)getPhotoFromName:(NSString *)name filePath:(NSString *)filePath {

//    NSString *tmpDir =  NSTemporaryDirectory();

//    NSString *uniquePath=[[paths objectAtIndex:0] stringByAppendingPathComponent:name];

//    BOOL blHave=[[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"%@%@",tmpDir,name]];

BOOL blHave=[[NSFileManager defaultManager] fileExistsAtPath: filePath];

if (!blHave) {

return nil;

}else

{

NSData *data = [NSData dataWithContentsOfFile:filePath];

UIImage *img = [[UIImage alloc] initWithData:data];

return img;

}

}

//对图片尺寸进行压缩--

-(UIImage*)imageWithImage:(UIImage*)image scaledToSize:(CGSize)newSize {

// Create a graphics image context

UIGraphicsBeginImageContext(newSize);

// Tell the old image to draw in this new context, with the desired

// 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;

}

//保存新的图片 永久保存到沙盒

-(NSString *)saveNewImage:(UIImage *)image WithImageName:(NSString *)imageName{

//xxxx.png

NSString *newName = [imageName stringByReplacingOccurrencesOfString:@".png" withString:@""];

newName = [imageName stringByReplacingOccurrencesOfString:@".jpg" withString:@""];

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);

NSString *filePath = [[paths objectAtIndex:0]stringByAppendingPathComponent:[NSString stringWithFormat:@"%@New.png",newName]];

//校验该文件名是否已经存在

if([[NSFileManager defaultManager] fileExistsAtPath:filePath]){

filePath = [[paths objectAtIndex:0]stringByAppendingPathComponent:[NSString stringWithFormat:@"%@New02.png",newName]];

}

//    UIImageWriteToSavedPhotosAlbum(image, self, nil, NULL);

[UIImagePNGRepresentation(image) writeToFile:filePath atomically:YES];

return filePath;

}

@end



手机拍照上传 出现问题(取不到图片) 解决方案:

由于用手机直接拍照上传传给压缩插件的不再是文件的路径,而是

assets-library://asset/asset.JPG?id=72CABA8E-68C0-413E-A3D5-256585CF3B42&ext=JPG 这种图片的url.

所以原先做的不再通用,需要做判断分开处理:

- (void)compress:(CDVInvokedUrlCommand *)command {

NSString *fullPath = command.arguments[0];

__block UIImage *targetImage = [[UIImage alloc]init];

NSString *imageName  = [[NSString alloc]init];

if( [fullPath rangeOfString:@"file://"].location != NSNotFound){

imageName = [fullPath lastPathComponent];

fullPath = [fullPath stringByReplacingOccurrencesOfString:@"file://" withString:@""];

targetImage = [self getPhotoFromName:imageName filePath:fullPath];

} else {

imageName = @"assetTarget";

ALAssetsLibrary  *lib = [[ALAssetsLibrary alloc] init];

dispatch_semaphore_t sema = dispatch_semaphore_create(0);

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{

[lib assetForURL:[NSURL URLWithString:fullPath] resultBlock:^(ALAsset *asset) {

//在这里使用asset来获取图片

targetImage  = [self fullResolutionImageFromALAsset:asset];

//信号量 通知 +1

dispatch_semaphore_signal(sema);

}

failureBlock:^(NSError *error){

dispatch_semaphore_signal(sema);

}];

});

//阻塞进程 直到 图片处理完毕

dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);

}

//    NSString *imagePath = [fullPath stringByReplacingOccurrencesOfString:[@"/" stringByAppendingString:imageName] withString:@""];

UIImage *newImage = [self imageWithImage:targetImage scaledToSize:CGSizeMake(480, 720)];

NSString *path = [self saveNewImage:newImage WithImageName:imageName];

//    NSString *jsCallback = [NSString stringWithFormat:@"cordova.fireDocumentEvent('compress',%@)", path];

CDVPluginResult *commandResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:path];

[self.commandDelegate sendPluginResult:commandResult callbackId:command.callbackId];

//    [self.commandDelegate evalJs:path];

}

- (UIImage *)fullResolutionImageFromALAsset:(ALAsset *)asset

{

ALAssetRepresentation *assetRep = [asset defaultRepresentation];

CGImageRef imgRef = [assetRep fullResolutionImage];

UIImage *img = [UIImage imageWithCGImage:imgRef

scale:assetRep.scale

orientation:(UIImageOrientation)assetRep.orientation];

return img;

}

这里有几点一定要格外注意:

1.拍照的文件名: 不能再直接取了。所以我们给了一个固定的文件名。

2.图片的Url需要经过处理才能转化为UIImage.

3.  assetForUrl这个Block是异步的方法。但是不适合我们。这种情况下我们需要同步执行,先获取uiimage才能执行其他的事。所以,此处通过

阻塞线程的方法来控制执行顺序。

你可能感兴趣的:(ionic插件-图片压缩ios端)