アプリ内でreact-native
、写真を撮って新しいカスタム アルバムに保存する必要があります。アルバムはメニューの写真からアクセスできないようにする必要があるため、アルバムを非公開にする必要があるため、キャプチャした写真はアプリ自体からのみアクセスできます。react-native-fs
ウェブで検索したところ、またはで可能だと思いますreact-native-fetch-blob
が、 でしか動作しないようAndroid
です。しかし、それはまさに私が必要としているものではありません。ドキュメント、例、コードなどを教えてください。
これは、ユーザーが写真を撮ってカメラロールに保存し、必要に応じて写真にアクセスできる、私が既に作成した現在のCamera
コンポーネントです。
import React, { Component } from 'react';
import {CardItem, Content, Container, Body, Left, Icon, Header, Right, Footer, FooterTab, Button } from 'native-base';
import {
Platform,
StyleSheet,
Dimensions,
Text,
ListView,
View,
Alert,
TouchableOpacity,
Image,
CameraRoll,
ScrollView
} from 'react-native';
import {Actions} from 'react-native-router-flux';
import { RNCamera } from 'react-native-camera';
const instructions = Platform.select({
ios: 'Press Cmd+R to reload,\n' +
'Cmd+D or shake for dev menu',
android: 'Double tap R on your keyboard to reload,\n' +
'Shake or press menu button for dev menu',
});
const {width, height} = Dimensions.get("window"),
vw = width / 100
vh = height / 100
export default class Camera extends Component {
constructor(props)
{ super(props)
this.state = {
buffer: false,
bufferImage: '',
dataSource: new ListView.DataSource({
rowHasChanged: (row1, row2) => true
}),
galleryON: false,
selectedImgTmstmp: '',
cameraType: 'RNCamera.Constants.Type.back',
flashMode: false,
cameraSelf: true
}
}
renderRow(img) {
clr = this.state.selectedImgTmstmp===img.node.timestamp?'blue':'grey';
return(
<CardItem button horizontal={false} onPress={()=>this.setState({selectedImgTmstmp: img.node.timestamp})}
style={{flexDirection: 'column',borderWidth: 3,borderRadius: 4,padding: 0, marginBottom: 5,
borderColor: clr,height: height/4, width: '48%'}}>
<Image
style={{
width: '100%',
height: '100%',
}}
source={{ uri: img.node.image.uri }}
/>
</CardItem>
);
}
render() {
if(this.state.galleryON){
return(
<Container>
<Content style={{backgroundColor: '#d8d8d8',height: '100%',width: width}}>
<ListView contentContainerStyle={{justifyContent: 'space-around',flexDirection: 'row', flexWrap: 'wrap'}}
dataSource={this.state.dataSource}
enableEmptySections={true}
renderRow={(rowData)=>this.renderRow(rowData)}>
</ListView>
</Content>
<View style={{flexDirection: 'row',width: width, height: 40, backgroundColor: '#ff5a00', alignItems: 'center', justifyContent: 'center'}}>
<Left style={{flex: 1, margin: 5}}>
<Text onPress={()=>this.setState({galleryON: false, selectedImgTmstmp: ''})} style={{fontWeight: 'bold', fontSize: 15}}>Cancel</Text>
</Left>
<Body style={{flex: 2}}>
<Text>Select Image</Text>
</Body>
<Right style={{flex: 1, margin: 5}}>
<Text onPress={()=>this.state.selectedImgTmstmp===''?null:Actions.pop()} style={{fontWeight: 'bold', fontSize: 15}}>Proceed</Text>
</Right>
</View>
</Container>
);
}
return (
this.state.buffer===false?
<Container style={styles.container}>
<Header style={{backgroundColor: '#000000',borderBottomWidth: 1, borderColor: '#FFF'}}>
<Left>
<Button transparent onPress={()=>this.setState({flashMode: !this.state.flashMode})}>
<Icon style={{color: '#FFF'}} name={this.state.flashMode?'ios-flash-outline':'ios-flash'}/>
</Button>
</Left>
<Right>
<Button transparent onPress={()=>this.setState({cameraSelf: !this.state.cameraSelf})}>
<Icon style={{color: '#FFF'}} name='ios-reverse-camera-outline'/>
</Button>
</Right>
</Header>
<RNCamera
ref={ref => {
this.camera = ref;
}}
style = {styles.preview}
type={this.state.cameraSelf?RNCamera.Constants.Type.front:RNCamera.Constants.Type.back}
flashMode={this.state.flashMode?RNCamera.Constants.FlashMode.on:RNCamera.Constants.FlashMode.off}
permissionDialogTitle={'Permission to use camera'}
permissionDialogMessage={'We need your permission to use your camera phone'}
/>
<View style={{flexDirection: 'row', justifyContent: 'space-between', height: '10%', alignItems: 'center',backgroundColor: '#000000'}}>
<TouchableOpacity style={{ height: 40, margin: 5}} onPress={()=>Actions.pop()}>
<Text style={{color: '#FFFF', fontSize: 25}}>Cancel</Text>
</TouchableOpacity>
<TouchableOpacity style={{ height: 40, margin: 5}} onPress={this.takePicture.bind(this)}>
<Icon style={{color: '#FFF', fontSize: 40}} name='ios-radio-button-on'/>
</TouchableOpacity>
<TouchableOpacity style={{ height: 40, margin: 5}} onPress={()=>this.getGallery()}>
<Text style={{color: '#FFFF', fontSize: 25}}>Photos</Text>
</TouchableOpacity>
</View>
</Container>
:
<Container style={{width: width, height: height, alignItems: 'center'}}>
<View style={{width: width, height: height, flexDirection: 'column'}}>
<Image source={{uri: this.state.bufferImage}} style={{width: '100%', height: '90%'}}/>
<View style={{flexDirection: 'row', justifyContent: 'space-between', height: '10%', alignItems: 'center',backgroundColor: '#000000'}}>
<TouchableOpacity style={{ height: 40, margin: 5}} onPress={()=>this.setState({bufferImage: '', buffer: false})}>
<Text style={{color: '#FFFF', fontSize: 25}}>Cancel</Text>
</TouchableOpacity>
<TouchableOpacity style={{ height: 40, margin: 5}} onPress={()=>this.savePictureToRoll(this.state.bufferImage)}>
<Text style={{color: '#FFFF', fontSize: 25}}>Done</Text>
</TouchableOpacity>
</View>
</View>
</Container>
);
}
getDataSource(posts) {
return this.state.dataSource.cloneWithRows(posts);
}
getGallery(){
CameraRoll.getPhotos({
first: 100,
assetType: 'Photos'
})
.then(photos => {
this.setState({dataSource: this.getDataSource(photos.edges), galleryON: true},()=>console.log(this.state.dataSource))
})
}
takePicture = async function() {
if (this.camera) {
const options = { quality: 0.5, base64: true };
const data = await this.camera.takePictureAsync(options)
console.log("DATA: ",data);
console.log(data.uri);
this.setState({buffer: true,bufferImage: data.uri})
}
};
savePictureToRoll(uri){
console.log("DATA.URI: ",this.state.bufferImage);
CameraRoll.saveToCameraRoll(uri, 'photo');
this.setState({bufferImage: '', buffer: false},()=>Alert.alert("IMAGE SAVED"), Actions.pop())
}
}