美文网首页Ionic Framework
ionic插件-图片压缩ios端

ionic插件-图片压缩ios端

作者: docC2Y | 来源:发表于2016-07-29 09:58 被阅读387次

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

    在模拟器上地址格式是这样的:   @"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端

        本文链接:https://www.haomeiwen.com/subject/bhhzjttx.html