React Native学习之CameraRoll API

CameraRoll 模块提供了对手机中保存的图片、视频文件进行遍历访问与操作。提供两个静态方法:getPhotossaveToCameraRoll / saveImageWithTag

getPhotos

可以得到手机中所有的图片和视频(不仅仅是使用摄像头拍摄的照片、视频,还有各个应用自己下载到手机的图片与视频)

static getPhotos(params: object)

返回一个带有图片标识符 JSON 对象的 Promise

params:对象,一些筛选的规则,有4个成员变量

  • first:数值,希望获取多少张图片的信息
  • groupTypes:字符串,默认为SavedPhotos [Album All Event Faces Library PhotoStream],仅支持IOS平台,用来指定获取图片或视频的类型
  • assetType:字符串,默认为Photos [All Videos],表示只获取图片
  • after:字符串,用来记录上一次获取图片的结束标志,方便可以接着上次的位置继续获取。它的值不能由开发者随意赋予,而是应当在上一次获取图片后保存其值。通常,在Android平台,一开始就给这个值为null,但是在IOS平台,设置为null会抛一个无法捕捉的异常,导致红屏。

注意:不管是Android平台还是iOS平台,得到的image对象,可以作为一个整体,传递给Image组件,用来显示图片。

可以分批次读取手机中的所有图片:监听ScrollView滑动到底部时,继续getPhotos,这时需要用after成员变量,递归调用getPhotos,当page_info.has_next_page = false时返回。

CameralRoll 在 iOS 平台中需要添加链接库才能运行,否则报错找不到API:

  • node_modules\react-native\Libraries\CameraRoll下的 Xcode 项目文件RCTCameraRoll.xcodeproj拖动到当前 Xcode 项目的 Libraries 目录。
  • 选中当前项目,在右边选择 Build Phases,点击打开子项目 Link Binary With Libraris。
  • 打开第一步插入的RCTCameraRoll.xcodeproj,再打开它的子目录 Products,将子目录下的libRCTCameraRoll.a文件拖到 Link Binary With Libraris 列表中。
  • 使用 Xcode 重新运行项目。

saveToCameraRoll 和 saveImageWithTag(已过时)

保存一个图片到相册

static saveToCameraRoll(tag, type?)
static saveImageWithTag(tag)

返回一个Promise,操作成功时返回新的URI

在安卓上,tag 参数是一个本地URI(是把本地的图片保存到相册中),例如"file:///sdcard/img.png".

在iOS设备上 tag 参数可能是以下之一:

  • 本地URI
  • 资源库的标签
  • 非以上两种类型,表示图片数据将会存储在内存中(并且在本进程持续的时候一直会占用内存)。

系统能够自动识别文件类型, 你也可以传入一个可选的 type 参数,参数值必须为 'photo' 或者 'video' 之一。

rn-camera-roll

CameraRoll暂时还不是特别完善,推荐一个跨平台的rn-camera-roll

rn-camera-rollhttps://www.npmjs.com/package/rn-camera-roll

安装组件

npm install rn-camera-roll --save

使用组件

iOS:导入库

node_modules/react-native/Libraries/CameraRoll/RCTCameraRoll.xcodeproj

Android(react-native >= v0.15):

(1)自动更新gradle文件

react-native link rn-camera-roll

(2)在 MainActivity 中注册组件包(需重新编译)

package cc.rnapp;

import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;

import com.facebook.react.LifecycleState;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactRootView;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;

// IMPORT HERE 
import fr.bamlab.rncameraroll.CameraRollPackage;
// --- 

public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler {

    private ReactInstanceManager mReactInstanceManager;
    private ReactRootView mReactRootView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mReactRootView = new ReactRootView(this);

        mReactInstanceManager = ReactInstanceManager.builder()
                .setApplication(getApplication())
                .setBundleAssetName("index.android.bundle")
                .setJSMainModuleName("index.android")
                .addPackage(new MainReactPackage())

                // REGISTER PACKAGE HERE 
                .addPackage(new CameraRollPackage())
                // --- 
                .setUseDeveloperSupport(BuildConfig.DEBUG)
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build();

        mReactRootView.startReactApplication(mReactInstanceManager, "example", null);

        setContentView(mReactRootView);
    }

    ...

CameraRoll 范例

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from 'react';
import {
    AppRegistry,
    CameraRoll,
    Image,
    ListView,
    ScrollView,
    StyleSheet,
    Text,
    View
} from 'react-native';

let fetchParams = {
    first: 10,
    assetType: 'Photos',
    //groupTypes in not supported on Android
    // groupTypes:'All',
};

let imgUrl = 'http://www.ouloon.com/images/';

class RNAPP extends Component {
    constructor(props) {
        super(props);
        this.state = {
            images: []
        };
    }

    render() {
        return (
            <ScrollView>
                <View style={styles.row}>
                    <View style={styles.flex_1} >
                        <Image
                            resizeMode='stretch'
                            style={[styles.imgHeight, styles.m5]}
                            source={{ uri: imgUrl + 'ReactNative.jpg' }}
                            />
                    </View>
                    <View style={styles.flex_1} >
                        <Image
                            resizeMode='stretch'
                            style={[styles.imgHeight, styles.m5]}
                            source={{ uri: imgUrl + 'Android.jpg' }}
                            />
                    </View>
                </View>

                <View>
                    <Text
                        onPress={this.saveImg.bind(this, 'ReactNative.jpg', 'Android.jpg')}
                        style={styles.saveImg}
                        >
                        保存图片到相册
                    </Text>
                </View>

                <View style={styles.imageGrid} >
                {
                    this.state.images.map((image) =>
                        <Image
                            style={styles.image}
                            resizeMode='stretch'
                            source={image}
                            key={image.uri}
                            />
                    )
                }
                </View>
            </ScrollView>
        );
    }

    componentDidMount() {
        let _that = this;
        //从0.20.0版本开始支持返回Promise机制
        CameraRoll.getPhotos(fetchParams).then(
            (data) => {
                console.log(data);
                let edges = data.edges;
                //.map 是针对数组里的每一个元素,调用回调函数
                //第一个参数是元素,第二个参数是下标,然后把每次调用的返回值按顺序再组织成一个新的数组
                let images = edges.map((edge) => {
                    return edge.node.image;
                });
                _that.setState({
                    images: images,
                });
            }
        ).catch(error => {
            console.log('错误: ' + error);
        });
    }

    saveImg(img1, img2) {
        let _that = this;
        //CameraRoll.saveImageWithTag(imgUrl + img1).then(
        CameraRoll.saveToCameraRoll(imgUrl + img1, 'photo').then(
            (url) => {
                if (url) {
                    let images = _that.state.images;
                    //unshift() 方法可向数组的开头添加一个或更多元素,并返回新的长度。
                    images.unshift({
                        uri: url,
                    });
                    _that.setState({
                        images: images,
                    });

                    //继续保存第二张图片
                    //CameraRoll.saveImageWithTag(imgUrl + img2).then(
                    CameraRoll.saveToCameraRoll(imgUrl + img2, 'photo').then(
                        (url) => {
                            images.unshift({
                                uri: url,
                            });
                            _that.setState({
                                images: images,
                            });
                            alert('图片全部保存成功');
                        }
                    ).catch(
                        error => {
                            alert('保存第二张照片失败: ' + error);
                        }
                    );
                }
            }
        ).catch(error => {
            alert('保存第一张照片失败: ' + error);
        });
    }
}

const styles = StyleSheet.create({
    flex_1: {
        flex: 1,
    },
    m5: {
        marginLeft: 5,
        marginRight: 5,
        borderWidth: 1,
        borderColor: '#ddd',
    },
    row: {
        flexDirection: 'row',
    },
    imageGrid: {
        flex: 1,
        flexDirection: 'row',
        flexWrap: 'wrap',
        justifyContent: 'center',
    },
    image: {
        width: 100,
        height: 100,
        margin: 10,
    },
    imgHeight: {
        height: 180,
    },

    saveImg: {
        flex: 1,
        height: 30,
        textAlign: 'center',
        textAlignVertical: 'center',
        marginTop: 20,
        color: '#FFF',
        lineHeight: 20,
        borderRadius: 5,
        marginLeft: 5,
        marginRight: 5,
        fontWeight: 'bold',
        backgroundColor: '#3BC1FF',
    },
});

AppRegistry.registerComponent('RNAPP', () => RNAPP);

版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/02/25/react-native-learning-cameraroll-api/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
海报
React Native学习之CameraRoll API
CameraRoll 模块提供了对手机中保存的图片、视频文件进行遍历访问与操作。提供两个静态方法:getPhotos和saveToCameraRoll / saveImageWithTag getPhotos 可以……
<<上一篇
下一篇>>
文章目录
关闭
目 录