iOS第三方之阿里云OSS(保存圖片)

目錄

集成

# 阿里云
pod 'AliyunOSSiOS', '~> 2.6.0'

#import <AliyunOSSiOS/AliyunOSSiOS.h>

封裝成工具類,方便使用

YTTool.h

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "AliyunOSSiOS/OSSService.h"



typedef void(^ResultBlock)(BOOL isOK,NSString *url);
typedef void(^Progress)(float progress);
typedef void(^ResultBlockT)(BOOL isOK,NSArray<NSString *> *imgNameArr);

@interface YTTool : NSObject


/**
 *  異步上傳 單張圖片
 *
 *  @param image         要上傳的圖片
 *  @param progressBlock 上傳圖片進度
 *  @param resultBlock   上傳圖片結(jié)果
 */
+(void)uploadPhotoAsync:(UIImage *)image progress:(Progress)progressBlock resultBlock:(ResultBlock)resultBlock;


/**
 *  同步上傳 單張圖片
 *
 *  @param image 要上傳的圖片
 *
 *  @return 上傳成功后返回的Url
 */
+(NSString *)uploadPhotoSync:(UIImage *)image progress:(Progress)progressBlock;


/**
 *  異步上傳 多張圖片
 *
 *  @param imageArr      要上傳的圖片數(shù)組
 *  @param progressBlock 上傳圖片進度
 *  @param resultBlock   上傳圖片結(jié)果
 *  @param isAsync       是否異步
 */
+(void)uploadPhotos:(NSArray<UIImage *> *)imageArr progress:(Progress)progressBlock resultBlock:(ResultBlockT)resultBlock isAsync:(BOOL)isAsync;
@end

YTTool.m

#import "YTTool.h"

// AccessKey
NSString * const AccessKey = @"LTAIULEB2J0Otax0";
// SecretKey
NSString * const SecretKey = @"zXXeirYoRw1qdd4ZRLrhwkOCEriw0R";
// 與OSS文件夾名對應(yīng)
NSString * const PUBLIC_BUCKET = @"kachamao";
//
NSString * const ENDPOINTIMAGE = @"http://oss-cn-shanghai.aliyuncs.com";
// 子文件夾
NSString * const OBJECT_KEY = @"CaChaCat_App_img";

//
NSString * const MultipartUploadObjectKey = @"multipartUploadObject";
//
CGFloat const kPix = 750;


// 修飾全局,作用域僅限于本類
static OSSClient * client;


@implementation YTTool

// 初始化OSS客戶端
+ (void)initOSSClient{
    
    // 1. credential
    id<OSSCredentialProvider> credential = [[OSSPlainTextAKSKPairCredentialProvider alloc] initWithPlainTextAccessKey:AccessKey secretKey:SecretKey];

    // 2. OSSClient配置參數(shù)
    OSSClientConfiguration *config = [OSSClientConfiguration new];
    // 設(shè)置 是否開啟后臺傳輸
    config.enableBackgroundTransmitService = NO;
    // 設(shè)置 最大重試次數(shù)
    config.maxRetryCount = 3;
    // 設(shè)置 請求超時時間
    config.timeoutIntervalForRequest = 20;
    // 設(shè)置 單個object下載最長持續(xù)時間
    config.timeoutIntervalForResource = 24 * 60 * 60;

    // 3. 初始OSS化客戶端
    client = [[OSSClient alloc]initWithEndpoint:ENDPOINTIMAGE credentialProvider:credential clientConfiguration:config];
}

// 異步上傳 單張圖片
+ (void)uploadPhotoAsync:(UIImage *)image progress:(Progress)progressBlock resultBlock:(ResultBlock)resultBlock{
    
    OSSPutObjectRequest *put=[self getPutWithImage:image progress:progressBlock];
    
    // 2.上傳
    OSSTask *putTast = [client putObject:put];
    [putTast continueWithBlock:^id _Nullable(OSSTask * _Nonnull task) {
        if (!task.error){       // 上傳成功
            NSLog(@"上傳成功");
            dispatch_async(dispatch_get_main_queue(), ^{
                
                // 上傳成功后的圖片UrlStr
                NSString *str=[[ENDPOINTIMAGE componentsSeparatedByString:@"http://"] lastObject];
                NSString *urlString=[NSString stringWithFormat:@"https://%@.%@/%@",PUBLIC_BUCKET,str,put.objectKey];
                resultBlock(YES,urlString);
            });
        }else{                  // 上傳失敗
            NSLog(@"上傳失敗:%@",task.error);
            dispatch_async(dispatch_get_main_queue(), ^{
                resultBlock(NO,nil);
            });
        }
        return nil;
    }];
}
// 同步上傳 單張圖片
+ (NSString *)uploadPhotoSync:(UIImage *)image progress:(Progress)progressBlock{
    
    OSSPutObjectRequest *put=[self getPutWithImage:image progress:progressBlock];
    
    // 2.上傳
    OSSTask *putTast = [client putObject:put];
    [[putTast continueWithBlock:^id _Nullable(OSSTask * _Nonnull task) {
        if (!task.error){
            NSLog(@"上傳成功");
        }else{
            NSLog(@"上傳失敗:%@",task.error);
        }
        return nil;
    }] waitUntilFinished];
    
    
    // 上傳成功后的圖片UrlStr
    NSString *str=[[ENDPOINTIMAGE componentsSeparatedByString:@"http://"] lastObject];
    NSString *urlString=[NSString stringWithFormat:@"https://%@.%@/%@",PUBLIC_BUCKET,str,put.objectKey];
    return urlString;
}
// 創(chuàng)建請求 OSSPutObjectRequest
+(OSSPutObjectRequest *)getPutWithImage:(UIImage *)image progress:(Progress)progressBlock{
    
    // 0.初始化客戶端
    [self initOSSClient];
    
    // 1.上傳請求
    OSSPutObjectRequest *put = [OSSPutObjectRequest new];
    // 1.1.設(shè)置bucketName (文件夾名,與OSS對應(yīng))
    put.bucketName = PUBLIC_BUCKET;
    // 1.2.文件名路徑
    NSTimeInterval timeInterval =[[NSDate date] timeIntervalSince1970];
    NSString *objectName = [NSString stringWithFormat:@"%@/%@_img_%d.png",[self dirPath],[self timeStringWithDataTimeToDate:timeInterval],((arc4random()% 100000000) + 10000)];
    put.objectKey = objectName;
    // 1.3.上傳對象(圖片data)
    put.uploadingData = [self imageCompressForSize:image targetPx:kPix];
    // 1.4.上傳進度
    put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) {
        float progress = (float)totalByteSent/totalBytesExpectedToSend;
        progressBlock(progress);
    };
    
    return put;
}


// 上傳多張圖片
+(void)uploadPhotos:(NSArray<UIImage *> *)imageArr progress:(Progress)progressBlock resultBlock:(ResultBlockT)resultBlock isAsync:(BOOL)isAsync{
    
    // 0.初始化客戶端
    [self initOSSClient];
    
    // 1.線程隊列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    // 1.1最大線程數(shù)
    queue.maxConcurrentOperationCount = imageArr.count;
    
    //
    NSMutableArray *callBackNames = [NSMutableArray array];
    int i = 0;
    for (UIImage *image in imageArr){
        if (image){
            
            // 線程
            NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
                
                // 1.上傳請求
                OSSPutObjectRequest *put = [OSSPutObjectRequest new];
                // 1.1.設(shè)置bucketName (文件夾名,與OSS對應(yīng))
                put.bucketName = PUBLIC_BUCKET;
                // 1.2.文件名+路徑
                NSTimeInterval timeInterval =[[NSDate date] timeIntervalSince1970];
                NSString *objectName = [NSString stringWithFormat:@"%@/%@_img_%d.png",[self dirPath],[self timeStringWithDataTimeToDate:timeInterval],((arc4random()% 100000000) + 10000)];
                put.objectKey = objectName;

                // iconName
                NSString *encodingString = [[NSString stringWithFormat:@"http://kachamao.oss-cn-shanghai.aliyuncs.com/%@",objectName]stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
                [callBackNames addObject: encodingString];
                
                // 1.3.上傳對象(內(nèi)存中)
                put.uploadingData = [self imageCompressForSize:image targetPx:kPix];

                //
                OSSTask * putTask = [client putObject:put];
                [putTask continueWithBlock:^id(OSSTask *task){
                     
                     if (task.error){
                         OSSLogError(@"%@", task.error);
                     }
                    
                     OSSPutObjectResult * result = task.result;
                     NSLog(@"Result - requestId: %@, headerFields: %@",
                           result.requestId,
                           result.httpResponseHeaderFields);
                     return nil;
                 }]; // 阻塞直到上傳完成
                
                
                if (isAsync) {
                    if (image == imageArr.lastObject) {
                        NSLog(@"upload object finished!");
                        if (resultBlock) {
                            resultBlock(true,callBackNames);
                        }
                    }
                }
            }];
            if (queue.operations.count != 0) {
                [operation addDependency:queue.operations.lastObject];
            }
            [queue addOperation:operation];
        }
        i++;
    }
    
    if (!isAsync) {
        [queue waitUntilAllOperationsAreFinished];
        if (resultBlock) {
            if (resultBlock) {
                resultBlock(true,[NSArray arrayWithArray:callBackNames]);
            }
        }
    }
}



// 文件路徑(會在oss官網(wǎng)上生成文件夾路徑)
+ (NSString *)dirPath{
    NSDateFormatter *formater = [NSDateFormatter new];
    [formater setDateFormat:@"/yyyy/MM/yyyMMdd"];
    NSString *str = [formater stringFromDate:[NSDate date]];
    
    return [[OBJECT_KEY mutableCopy] stringByAppendingString:str];
}


/**
 圖片壓縮的處理邏輯:
 
 一 尺寸壓縮(一般參照像素為1280)
 a. 寬高均<=1280px時    圖片尺寸保持不變
 b. 寬高均>1280px時     圖片寬高比<=2,則將圖片寬或者高取大的等比壓縮至1280px; 圖片寬高比>2時,則寬或者高取小的等比壓縮至1280px;
 c. 寬或高某一個>1280px,另一個<1280px時  圖片寬高比>2時,則寬高尺寸不變;圖片寬高比≤2時,則將圖片寬或者高取大的等比壓縮至1280px.
 
 二 質(zhì)量壓縮
 一般壓縮在90%
 */

#pragma mark -- 圖片壓縮方法
+ (NSData *)imageCompressForSize:(UIImage *)sourceImage targetPx:(NSInteger)targetPx{
    
    //
    BOOL drawImge = NO;              // 是否需要重繪圖片 默認是NO
    CGFloat scaleFactor = 0.0;       // 壓縮比例
    CGFloat scaledWidth = targetPx;  // 壓縮后的寬度 默認是參照像素1280px
    CGFloat scaledHeight = targetPx; // 壓縮后的高度 默認是參照像素1280px
    
    
    // 壓縮尺寸
    // 新圖片(尺寸壓縮后的)
    UIImage *newImage = nil;
    // 原size
    CGSize imageSize = sourceImage.size;
    CGFloat width = imageSize.width;
    CGFloat height = imageSize.height;
    // 判斷尺寸
    if (width < targetPx && height < targetPx) {            // a.寬高均<=參照像素時:尺寸不變
        newImage = sourceImage;
    }else if (width > targetPx && height > targetPx) {      // b.寬或高均>1280px時
        drawImge = YES;
        CGFloat factor = width / height;
        if (factor <= 2) {  // b.1圖片寬高比≤2,則將圖片寬或者高取大的等比壓縮至1280px
            if (width > height) {
                scaleFactor  = targetPx / width;
            } else {
                scaleFactor = targetPx / height;
            }
        } else {            // b.2圖片寬高比>2時,則寬或者高取小的等比壓縮至1280px
            if (width > height) {
                scaleFactor  = targetPx / height;
            } else {
                scaleFactor = targetPx / width;
            }
        }
    }else if (width > targetPx &&  height < targetPx ) {    // c.寬高一個>1280px,另一個<1280px 寬大于1280
        if (width / height > 2) {
            newImage = sourceImage;
        } else {
            drawImge = YES;
            scaleFactor = targetPx / width;
        }
    }else if (width < targetPx &&  height > targetPx) {     // c.寬高一個>1280px,另一個<1280px 高大于1280
        if (height / width > 2) {
            newImage = sourceImage;
        } else {
            drawImge = YES;
            scaleFactor = targetPx / height;
        }
    }
    if (drawImge == YES) {      // 圖片需要重繪 按新寬高壓縮重繪圖片
        scaledWidth = width * scaleFactor;
        scaledHeight = height * scaleFactor;
        UIGraphicsBeginImageContext(CGSizeMake(scaledWidth, scaledHeight));
        [sourceImage drawInRect:CGRectMake(0, 0, scaledWidth,scaledHeight)];
        newImage =UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    }
    if (newImage == nil) {
        newImage = sourceImage;
    }
    
    
    
    // 質(zhì)量壓縮(圖片>200kb 時)
    NSData * scaledImageData = nil;
    if (UIImageJPEGRepresentation(newImage, 1) == nil) {
        scaledImageData = UIImagePNGRepresentation(newImage);
    }else{
        scaledImageData = UIImageJPEGRepresentation(newImage, 1);
        if (scaledImageData.length >= 1024 * 200) {
            scaledImageData = UIImageJPEGRepresentation(newImage, 0.5);
        }
    }
    
    return scaledImageData;
}

// yyyy-MM-dd 時間戳
+ (NSString *)timeStringWithDataTimeToDate:(NSTimeInterval)time{
    
    //
    NSDateFormatter *dateFormatter = nil;
    if (dateFormatter == nil) {
        dateFormatter = [[NSDateFormatter alloc] init];
        [dateFormatter setDateFormat:@"YYYY_MM_dd_hh_mm_ss"];
    }
    NSString *string = [dateFormatter stringFromDate:[NSDate dateWithTimeIntervalSince1970:(time)]];
    return string;
}

@end
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 阿里云對象存儲OSS,主要是用于存儲靜態(tài)資源文件,它提供了很多方便的操作圖片的方法(縮放旋轉(zhuǎn)水印等),在實現(xiàn)了OS...
    記住你姓李閱讀 10,862評論 0 9
  • 我在上一篇博客Linux本地數(shù)據(jù)上傳到阿里云OSS中介紹了如何將linux本地的數(shù)據(jù)上傳到阿里云的OSS,在這篇博...
    余含軍閱讀 6,132評論 3 0
  • 本文是新系列“從零開始搭建微服務(wù)”的開篇,該系列將圍繞微服務(wù)展開,重點在于動手搭建。 微服務(wù)是個很大的話題,關(guān)于微...
    isdom閱讀 8,875評論 3 41
  • mono是至今我覺得最得我心的app。 首次打開mono,是一個水母漂浮的動態(tài)畫面,以深藍色的海洋為主基調(diào),給人神...
    東東方閱讀 2,050評論 3 1
  • 在高考前十八年頭一次被自己最親的人說是撒謊的孩子,不知道怎么回事,當(dāng)我聽清楚一遍又一遍的‘撒謊’這兩個字時我反而冷...
    高三黨閱讀 652評論 1 1

友情鏈接更多精彩內(nèi)容