• ReactNative: 使用第三方库图像选择器react-native-image-picker和react-native-image-crop-picker


    一、简介

    同前面使用第三方库相机框架react-native-camera一样,对于原生的图片选择器的使用也有第三方框架提供。分别是react-native-image-picker和react-native-image-crop-picker。 react-native-image-picker库可以实现启动本地相册和照相机来采集图片,但是没有实现裁剪功能。针对头像上传的需求,一般都需要对图片进行裁剪,此时可以使用react-native-image-crop-picker库,该库同样实现了本地相册和照相机来采集图片,并且提供多选、图片裁剪等功能,支持iOS和Android两个平台。

    react-native-image-picker:https://github.com/react-native-community/react-native-image-picker,基本样式如下:

    react-native-image-crop-picker:https://github.com/ivpusic/react-native-image-crop-picker,基本样式如下:

    二、配置plist文件

    iOS10以后,访问用户的隐私文件需要授权,例如相册或者相机(录屏),因此需要打开Xcode并在项目的plist中添加授权字段。分别是NSCameraUsageDescription和NSPhotoLibraryUsageDescription以及NSMicrophoneUsageDescription(录制视屏需要访问麦克风)。

    三、react-native-image-picker

    1、安装:

    • 注意自己的React-Native版本号,选择对应的库进行安装。我使用的0.44.3版本RN,之前安装高版本的react-native-image-picker总是编译失败。就装了低版本的。

    • 命令行如下 
    //安装(本人安装的是低版本的:0.28.0)
    npm install react-native-image-picker@0.28.0 --save
    
    //链接(系统会自动在xcode中导入xcodeproj工程和.a静态包, link后面可以跟具体的库名,也可以不用跟)
    react-native link react-native-image-picker@0.28.0

    2、配置

    • 安装react-native-image-picker库后需要打开xcode添加它的.xcodeproj工程和libRNImagePicker.a静态包到项目中
    • 注意事项:如果开发者手动执行了安装步骤的第2条命令行 react-native link xxxxxx”,则这下面的两步就不用手动操作了,系统会帮助自动完成。

    3、API

    高版本和低版本的库其实差别也不是特别大,本人装的是低版本的,对低版本的api做一些简单的注释如下:

    declare module "react-native-image-picker" {
    
        //这个是操作ImagePicker的方法的回调信息(主要是操作界面被点击的信息和图片视屏的信息)
        interface Response {
            customButton: string;
            didCancel: boolean;
            error: string;
            data: string;
            uri: string;
            origURL?: string;
            isVertical: boolean;
             number;
            height: number;
            fileSize: number;
            type?: string;
            fileName?: string;
            path?: string;
            latitude?: number;
            longitude?: number;
            timestamp?: string;
        }
    
        //在默认操作界面上添加自定义文案的按钮
        interface CustomButtonOptions {
            name?: string;
            title?: string;
        }
    
        //在操作ImagePicker的方法之前,传入的一下配置选项。主要是界面的配置选项和相机以及图片视频的配置选项
        interface Options {
            title?: string;
            cancelButtonTitle?: string;
            takePhotoButtonTitle?: string;
            chooseFromLibraryButtonTitle?: string;
            customButtons?: Array<CustomButtonOptions>;
            cameraType?: 'front' | 'back';
            mediaType?: 'photo' | 'video' | 'mixed';
            maxWidth?: number;
            maxHeight?: number;
            quality?: number;
            videoQuality?: 'low' | 'medium' | 'high';
            durationLimit?: number;
            rotation?: number;
            allowsEditing?: boolean;
            noData?: boolean;
            storageOptions?: StorageOptions;
        }
    
        //关于存储相关的配置选项
        interface StorageOptions {
            skipBackup?: boolean;
            path?: string;
            cameraRoll?: boolean;
            waitUntilSaved?: boolean;
        }
    
    
        //ImagePicker的三方常用方法
        class ImagePicker {
    
            //选择图片(包括相机和图库选项)
            static showImagePicker(options: Options, callback: (response: Response) => void): void;
    
            //打开相机(可以拍照,也可以录制视频)
            static launchCamera(options: Options, callback: (response: Response) => void): void;
    
            //打开图库
            static launchImageLibrary(options: Options, callback: (response: Response) => void): void;
        }
    
        export = ImagePicker;
    
    }

    4、使用

     代码如下:

    /**
     * Sample React Native App
     * https://github.com/facebook/react-native
     * @flow
     */
    
    import React, { Component } from 'react';
    import {
        AppRegistry,
        StyleSheet,
        Text,
        TouchableHighlight,
        View
    } from 'react-native';
    
    const ImagePicker = require('react-native-image-picker');
    
    export default class App extends Component {
    
        //选择图片
        _showImagePicker(){
    
            //配置选项
            const options = {
                title: '选择图片',
                cancelButtonTitle: '取消',
                takePhotoButtonTitle: '拍照',
                chooseFromLibraryButtonTitle: '图库',
                customButtons: [
                    {name: 'share photo', title: '分享'},
                ],
                cameraType: 'back',
                mediaType: 'photo',
                videoQuality: 'high',
                durationLimit: 10,
                maxWidth: 300,
                maxHeight: 300,
                quality: 0.8,
                angle: 0,
                allowsEditing: false,
                noData: false,
                storageOptions: {
                    skipBackup: true
                }
            };
    
            //回调数据
            ImagePicker.showImagePicker(options, (response => {
                 console.log("response: "+response);
            }))
        }
    
        //打开相机
        _launchCamera(){
    
            //配置选项
            const options = {
                cameraType: 'front',  //前置摄像头
                mediaType: 'photo'    //进行拍照
            };
    
            //回调数据
            ImagePicker.launchCamera(options, (response => {
                console.log("response: "+response);
            }))
        }
    
        //打开图库
        _launchImageLibrary(){
    
            //配置选项
            const options = { mediaType: 'photo' };
    
            //回调数据
            ImagePicker.launchImageLibrary(options, (response => {
                console.log("response: "+response);
            }))
        }
    
        render() {
            return (
                <View style={styles.container}>
                    <TouchableHighlight onPress={this._showImagePicker.bind(this)}>
                        <Text style={{color:'red',fontSize:30}}>选择图片</Text>
                    </TouchableHighlight>
                    <TouchableHighlight onPress={this._launchCamera.bind(this)}>
                        <Text style={{color:'red',marginTop:30,fontSize:30}}>打开相机</Text>
                    </TouchableHighlight>
                    <TouchableHighlight onPress={this._launchImageLibrary.bind(this)}>
                        <Text style={{color:'red',marginTop:30,fontSize:30}}>打开图库</Text>
                    </TouchableHighlight>
                </View>
            );
        }
    }
    
    const styles = StyleSheet.create({
        container: {
            flex: 1,
            justifyContent: 'center',
            alignItems: 'center',
            backgroundColor: '#F5FCFF',
        }
    });
    
    AppRegistry.registerComponent('App', () => App);

    踩坑经验:0.28.0这个版本的库有点问题,打开相机和图库时,app会很慢,甚至严重到闪退。这是由于作者对于打开相机launchCamear和打开图库launchImageLibrary的方法,没有放在主线程中执行,修改库文件即可,如下:

    运行结果如下所示:

     

    四、react-native-image-crop-picker

    1、安装

    • 安装react-native-image-crop-picker也需要根据自己的ReactNative版本。在github上已经写明安装的要求,如下: 
    如果您使用的是react-native> = 0.60,请使用react-native-image-crop-picker版本> = 0.25.0。 否则,使用版本<0.25.0。
    • 命令行(同上)
    //安装
    npm install react-native-image-crop-picker@0.24.1 --save
    
    //链接
    react-native link react-native-image-crop-picker@0.24.1

    2、配置

    • 置步骤和上面的react-native-image-picker一样,不再赘述。但是注意,仍需要手动添加如下两个框架,否则会报错如下:

    dyld: Library not loaded: @rpath/QBImagePicker.framework/QBImagePicker
      Referenced from: /private/var/containers/Bundle/Application/1816C8C9-80A2-4860-919B-CD415E245C4C/RNDemo.app/RNDemo
      Reason: image not found

    3、API

    它的类构成也很简单,如下所示: 

    declare module "react-native-image-crop-picker" {
         
         //配置裁剪选项,在调用方法时需要传入的参数
         export interface Options {
            cropping?: boolean;
            width?: number;
            height?: number;
            multiple?: boolean;
            path?: string;
            includeBase64?: boolean;
            includeExif?: boolean;
            avoidEmptySpaceAroundImage?: boolean;
            cropperActiveWidgetColor?: string;
            cropperStatusBarColor?: string;
            cropperToolbarColor?: string;
            cropperToolbarTitle?: string;
            freeStyleCropEnabled?: boolean;
            cropperTintColor?: string;
            cropperCircleOverlay?: boolean;
            disableCropperColorSetters?: boolean;
            maxFiles?: number;
            waitAnimationEnd?: boolean;
            smartAlbums?: string[];
            useFrontCamera?: boolean;
            compressVideoPreset?: string;
            compressImageMaxWidth?: number;
            compressImageMaxHeight?: number;
            compressImageQuality?: number;
            loadingLabelText?: string;
            mediaType?: string;
            showsSelectedCount?: boolean;
            forceJpg?: boolean;
            showCropGuidelines?: boolean;
            hideBottomControls?: boolean;
            enableRotationGesture?: boolean;
            cropperCancelText?: string;
            cropperChooseText?: string;
        }
    
        //关于图片的信息
        export interface Image {
            path: string;
            size: number;
            data: null | string;
             number;
            height: number;
            mime: string;
            exif: null | object;
            cropRect: null | CropRect;
            filename: string;
            creationDate: string;
            modificationDate?: string;
    
        }
    
        //裁剪的局域信息
        export interface CropRect {
            x: number;
            y: number;
             number;
            height: number;
        }
    
        //打开选择器,返回值是一个Promise异步函数,结果是图片或图片数组
        export function openPicker(options: Options): Promise<Image | Image[]>;
       
        //打开相机,返回值是一个Promise异步函数,结果是图片或图片数组
        export function openCamera(options: Options): Promise<Image | Image[]>;
        
        //打开裁剪器,需要指定要裁剪资源的路径path ,返回值是一个Promise异步函数,结果是图片
        export function openCropper(options: Options): Promise<Image>;
        
        //清除所有临时缓存,返回值是一个Promise异步函数,无结果
        export function clean(): Promise<void>;
        
        //清除某一个资源的临时缓存,返回值是一个Promise异步函数,无结果
        export function cleanSingle(path: string): Promise<void>;
    
         //裁剪选择器 
        export interface ImageCropPicker {
            openPicker(options: Options): Promise<Image | Image[]>;
            openCamera(options: Options): Promise<Image | Image[]>;
            openCropper(options: Options): Promise<Image>;
            clean(): Promise<void>;
            cleanSingle(path: string): Promise<void>;
        }
    
        const ImageCropPicker: ImageCropPicker;
    
        export default ImageCropPicker;
    }

    4、使用

    针对api,简单使用如下:

    /**
     * Sample React Native App
     * https://github.com/facebook/react-native
     * @flow
     */
    
    import React, { Component } from 'react';
    import {
        AppRegistry,
        StyleSheet,
        Text,
        TouchableHighlight,
        View
    } from 'react-native';
    
    import ImageCropPicker from 'react-native-image-crop-picker';
    
    export default class App extends Component {
    
        //打开选择器: 裁剪单张图片
        _openPicker1(){
           const option = {  300, height: 400, mediaType:"photo", cropping: true };
           ImageCropPicker.openPicker(option).then(image =>{
               alert(image);
           }, (error) =>{
               alert(error);
           });
        }
    
        //打开选择器: 选择多张图片
        _openPicker2(){
            const option = {mediaType:"photo", multiple:true};
            ImageCropPicker.openPicker(option).then(images =>{
                alert(images);
            }, (error) =>{
                alert(error);
            });
        }
    
        //打开选择器: 选择视屏资源
        _openPicker3(){
            const option = { mediaType:"video" };
            ImageCropPicker.openPicker(option).then(video =>{
                alert(video);
            }, (error) =>{
                alert(error);
            });
        }
    
        //打开相机: 拍照
        _openCamera1(){
            const option = {  300, height: 400, mediaType:"photo", cropping: true };
            ImageCropPicker.openCamera(option).then(image =>{
                alert(image);
            }, (error) =>{
                alert(error);
            });
        }
    
        //打开相机: 视频
        _openCamera2(){
            const option = { mediaType:"video" };
            ImageCropPicker.openCamera(option).then(video =>{
                alert(video);
            },(error) =>{
                alert(error);
            });
        }
    
        //打开截取器: 直接裁剪指定路径下的图片
        _openCropper(){
            const option = { path:"car.png",  100, height: 100, mediaType:"photo", cropping: true };
            ImageCropPicker.openCropper(option).then(image => {
                alert(image);
            },(error) =>{
                alert(error);
            });
        }
    
        render() {
            return (
                <View style={styles.container}>
                    <TouchableHighlight onPress={this._openPicker1.bind(this)}>
                        <Text style={{color:'red',marginBottom:30,fontSize:25}}>打开选择器:裁剪单张图片</Text>
                    </TouchableHighlight>
                    <TouchableHighlight onPress={this._openPicker2.bind(this)}>
                        <Text style={{color:'red',marginBottom:30,fontSize:25}}>打开选择器:选择多张图片</Text>
                    </TouchableHighlight>
                    <TouchableHighlight onPress={this._openPicker3.bind(this)}>
                        <Text style={{color:'red',marginTop:0,fontSize:25}}>打开选择器:选择视屏资源</Text>
                    </TouchableHighlight>
                    <TouchableHighlight onPress={this._openCamera1.bind(this)}>
                        <Text style={{color:'red',marginTop:30,fontSize:25}}>打开相机: 拍照</Text>
                    </TouchableHighlight>
                    <TouchableHighlight onPress={this._openCamera2.bind(this)}>
                        <Text style={{color:'red',marginTop:30,fontSize:25}}>打开相机: 视频</Text>
                    </TouchableHighlight>
                    <TouchableHighlight onPress={this._openCropper.bind(this)}>
                        <Text style={{color:'red',marginTop:30,fontSize:25}}>打开裁剪器</Text>
                    </TouchableHighlight>
                </View>
            );
        }
    }
    
    const styles = StyleSheet.create({
        container: {
            flex: 1,
            justifyContent: 'center',
            alignItems: 'center',
            backgroundColor: '#F5FCFF',
        }
    });
    
    AppRegistry.registerComponent('App', () => App); 

    结果如下:

  • 相关阅读:
    如何开始学习编程? 这 3 步很重要
    php正则表达式验证手机/固定电话/邮箱/身份证/银行卡自定义函数
    【经验分享】-PHP程序员的技能图谱
    PHP程序员的技能图谱
    PHP程序员要掌握的技能
    冒泡排序
    文件下载方法
    加密,解密方法
    获取真实IP
    二维数组根据某个字段排序
  • 原文地址:https://www.cnblogs.com/XYQ-208910/p/12192729.html
Copyright © 2020-2023  润新知