【分享】游戏选取使用(多选)相册图片IOS&&Android

这东西会者不难,难者不会,网上的资料也比较分散,分享整理下,顺便增强巩固:blush:

选取相册(多选)【ios】

由于IOS自带的imagePickerController不支持多选,所以这里选用了ELCImagePickerController
GitHub:ELCImagePicker

下载后将ELCImagePicker文件夹拖入Xcode

在info.plist 增加2个权限
Privacy - Photo Library Additions Usage Description 否允许此APP保存图片到相册?
Privacy - Photo Library Usage Description 是否允许此APP使用相册?

[流程]
游戏中点击按钮-调用oc方法-oc中拉起相册-用户选择-回调oc-调用js-游戏内逻辑操作

1.调用oc方法 xxx.js

if(cc.sys.OS_IOS == cc.sys.os)
{
     jsb.reflection.callStaticMethod("RootViewController", "getImgData");
}
会调用RootViewController.mm 的 getImgData静态方法

2.拉起相册 RootViewController.mm

1⃣️引入头文件 与 设置代理

#import "ELCImagePickerController.h"
@interface RootViewController () <ELCImagePickerControllerDelegate,UINavigationControllerDelegate>
@property(nonatomic,strong)   ELCImagePickerController *elcPicker;
@end
static ELCImagePickerController *selectImage = nullptr;

2⃣️新增代理函数

#pragma mark - ELCImagePickerControllerDelegate Methods

- (void)elcImagePickerController:(ELCImagePickerController *)picker didFinishPickingMediaWithInfo:(NSArray *)info
{
    NSLog(@"Selected assets:");
    // NSLog(@"%@", assets);//
    [[[UIApplication sharedApplication] keyWindow].rootViewController  dismissViewControllerAnimated:YES completion:NULL];
    [RootViewController saveImage:info];
}

- (void)elcImagePickerControllerDidCancel:(ELCImagePickerController *)picker
{
    NSLog(@"Canceled.");
    [[[UIApplication sharedApplication] keyWindow].rootViewController  dismissViewControllerAnimated:YES completion:NULL];
}

3⃣️初始化
在RootViewController.mm 的viewDidLoad初始化

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];
    _elcPicker=[[ELCImagePickerController alloc] initImagePicker];
    _elcPicker.delegate = self;
    selectImage = _elcPicker;
}

4⃣️使用

//游戏中调用的方法
+(void) getImgData {
    
    [[RootViewController alloc] init];
    [[RootViewController alloc] selectPhoto]; //打开相册
 
}

-(void)selectPhoto{
    
    selectImage.maximumImagesCount = 9;//最多选择9张
    selectImage.imagePickerDelegate = self;
    selectImage.returnsOriginalImage = NO; //Only return the fullScreenImage, not the fullResolutionImage
    selectImage.returnsImage = YES; //Return UIimage if YES. If NO, only return asset location information
    selectImage.onOrder = NO; //For single image selection, do not display and return order of selected images
    //   selectImage.mediaTypes = @[(NSString *)kUTTypeImage]; //Supports image and
    UIViewController *topRootViewController = [[UIApplication sharedApplication] keyWindow].rootViewController;
    [topRootViewController presentViewController:selectImage animated:YES completion:nil];
}

到这里后会拉起相册,用户操作后会跳到上面的代理函数didFinishPickingMediaWithInfo

5⃣️处理
需要 #include “cocos/scripting/js-bindings/jswrapper/SeApi.h”

+(void)saveImage:(NSArray *)info
{
    std::string allImage = "";
    for (NSDictionary *dict in info) {
        UIImage* image=[dict objectForKey:UIImagePickerControllerOriginalImage];//UIImagePickerControllerEditedImage。//UIImagePickerControllerOriginalImage
        
        
        NSString* uuid = [[NSUUID UUID] UUIDString];
        NSString* fileName;
        fileName = [uuid stringByAppendingFormat:@".png"];
        std::string strFileName = [fileName UTF8String];
        
        std::string newImgPath = cocos2d::FileUtils::getInstance()->getWritablePath()  + strFileName;
        
        [UIImagePNGRepresentation(image) writeToFile:[NSString stringWithFormat:@"%s",newImgPath.c_str()] atomically:YES];//保存图片到应用内部,才能用 cc.loader.load 下载
        allImage = allImage + strFileName + ",";//图片名字用逗号分隔,传入js后再处理
    }
    
    
//    NSString *log = [NSString stringWithCString:allImage.c_str()
//                                       encoding:[NSString defaultCStringEncoding]];
//
//    NSLog(@"imgFilePath assets:  ============ %@" ,log);
    //调用js
    std::string jsCallStr = cocos2d::StringUtils::format("window.onSelectPhotoBack(\"%s\");", allImage.c_str());
    se::ScriptEngine::getInstance()->evalString(jsCallStr.c_str());
    
}

到这步我们就把选择的图片写到应用本地,然后把图片名字传回js啦,剩下的就是到js load 后使用

6⃣️使用

var self = this;
window.onSelectPhotoBack = function (photoPath) {
            console.log("onSelectPhotoBack  = " + photoPath)

            setTimeout(() => {
                self.list = [];
                var sp = photoPath.split(","); //分隔,得到图片名字数组list
                for (var i = 0; i < sp.length; i++) {
                    if(sp[i] == undefined || sp[i] == "") continue;
                    self.list.push(sp[i]);
                }

                Global.eventMgr.dispatchEvent({
                    name: Global.config.CustomEvent.PHOTO_VIEW_REFRESH
                });

            }, 500)


        };

//单个使用
    loadRes(url) {
        var self = this;
        url = url.replace(/\s+/g, "");

        if (cc.sys.OS_IOS == cc.sys.os) {
            var dirpath = jsb.fileUtils.getWritablePath();
            var filepath = url;

            cc.loader.load(dirpath + filepath, function (err, tex) {
                if (err) {
                    cc.error(err);
                } else {
                    var frame = new cc.SpriteFrame(tex);
                    self.getComponent(cc.Sprite).spriteFrame = frame;
                }
            });

        }

    },

});


【Android】 晚点再写 //todo

3赞

:grin:

那个,有第三方的库·····可以直接用,不过也需要自己桥接几个接口

第三方库叫什么名字呢

安卓我用的是 PictureSelector