how to transform image from gallery or camera into base64? - react-native

I have a function that takes the image from the gallery or camera and sends it to an area where the user can view it.
import React, {useState} from 'react';
import {View, TouchableOpacity, Text, StyleSheet, Image} from 'react-native';
import ImagePicker from 'react-native-image-picker';
export default function Upload() {
const [avatar, setAvatar] = useState();
function imagePickerCallback(data) {
if (data.didCancel) {
return;
}
if (data.error) {
return;
}
if (data.customButton) {
return;
}
if (!data.assets[0].uri) {
return;
}
setAvatar(data.assets[0]);
}
return (
<View style={styles.container}>
<Image
source={{
uri: avatar
? avatar.uri
: 'https://mltmpgeox6sf.i.optimole.com/w:761/h:720/q:auto/https://redbanksmilesnj.com/wp-content/uploads/2015/11/man-avatar-placeholder.png',
}}
style={styles.avatar}
/>
<TouchableOpacity
style={styles.button}
onPress={() =>
ImagePicker.launchCamera(imagePickerCallback)
}>
<Text style={styles.buttonText}>camera</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={() =>
ImagePicker.launchImageLibrary(imagePickerCallback)
}>
<Text style={styles.buttonText}>galery</Text>
</TouchableOpacity>
</View>
);
}
I'm filling the image source with the URI. I would like to know how to take this image and make it base64 to send it to firebase storage.
If I need to install a library, tell me which one to install.

If you read the library definition for options which is the first parameter. You can tell the library to return the base64 string. options: { includeBase64: true }
https://github.com/react-native-image-picker/react-native-image-picker#options
And that will return the below object with base64
https://github.com/react-native-image-picker/react-native-image-picker#asset-object
See below example:
import React, {useState} from 'react';
import {View, TouchableOpacity, Text, StyleSheet, Image} from 'react-native';
import ImagePicker from 'react-native-image-picker';
export default function Upload() {
const [avatar, setAvatar] = useState();
function imagePickerCallback(data) {
if (data.didCancel) {
return;
}
if (data.error) {
return;
}
if (data.customButton) {
return;
}
if (!data.assets[0].uri) {
return;
}
if((data.assets?.length ?? 0) > 0 && data.assets[0].base64){
//Here is my base64 string of assets[0]
}
setAvatar(data.assets[0]);
}
const options = {
includeBase64: true
}
return (
<View style={styles.container}>
<Image
source={{
uri: avatar
? avatar.uri
: 'https://mltmpgeox6sf.i.optimole.com/w:761/h:720/q:auto/https://redbanksmilesnj.com/wp-content/uploads/2015/11/man-avatar-placeholder.png',
}}
style={styles.avatar}
/>
<TouchableOpacity
style={styles.button}
onPress={() =>
ImagePicker.launchCamera(options, imagePickerCallback)
}>
<Text style={styles.buttonText}>camera</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={() =>
ImagePicker.launchImageLibrary(options, imagePickerCallback)
}>
<Text style={styles.buttonText}>galery</Text>
</TouchableOpacity>
</View>
);
}

Related

how to print the contents of a viewshot without display it in react native?

I am using the library react-native-view-shot and I am trying to print the contents of a viewshot without display it.
If I don't hide the contents I can print without a problem, but I need to hide the contents.
If I hide the viewshot and try to print the contents like:
import { StatusBar } from 'expo-status-bar';
import React, {Component} from 'react';
import {Button, ScrollView, StyleSheet, Text, TextInput, View, alert, Alert} from 'react-native';
import {discoverPrinters, pingPrinter, printImage, registerBrotherListener} from 'react-native-brother-printers';
import ViewShot from "react-native-view-shot";
export default class App extends Component {
state = {
displayContents: false
};
render() {
const {displayContents} = this.state;
return (
<ScrollView style={{flex: 1}}>
{displayContents && (
<ViewShot ref={(e) => {
this.viewShot = e;
}} options={{format: "jpg", quality: 0.9}}>
{ <Text style={{fontSize: 24}}>
print something
</Text> }
<Text style={{fontSize: 24}}>
printer test
</Text>
</ViewShot>
)}
<View style={styles.container}>
<Text>
Test Connection
</Text>
<Button title="Print from Manual" onPress={() => {
this.viewShot.capture().then(uri => {
// this.viewShot.capture().then(() => {
// console.log("do something with ", uri);
printImage(
{
"modelName": "Brother PT-P950NW",
"ipAddress": " 192.168.118.1",
},uri, {autoCut: false}).then(() => {
console.log("Discover Manual Successful");
}).catch((err) => {
console.log(err);
console.log("Discover Manual failed")
});
});
}}/>
</View>
</ScrollView>
);
}
}
I get this error message:
TypeError: undefined is not an object (evaluating '_this3.viewShot.capture')
It's possible do that ?

react native I want to designate one image as the default

I wrote the code to upload an image, but when I click remove image, a blue screen appears as a default. I want to designate this screen as one image.
import 'react-native-gesture-handler'
import * as React from 'react';
import{
StyleSheet,
View,
Text,
Image,
TouchableOpacity,
ToastAndroid,
Alert,
} from 'react-native';
import { Avatar } from 'react-native-paper';
import { launchImageLibrary } from 'react-native-image-picker';
import styled from 'styled-components';
const Container = styled.SafeAreaView`
flex : 1;
`;
export default function Profile(){
const [pic, Setpic] = React.useState('');
const setToastMsg = msg => {
ToastAndroid.showWithGravity(msg, ToastAndroid.SHORT, ToastAndroid.CENTER)
};
const uploadImage = () => {
let options = {
mediaType : 'photo',
quality : 1,
includeBase64 : true,
};
launchImageLibrary(options, response => {
if(response.didCancel){
setToastMsg('Cancelled image selection');
}
else if((response.errorCode == 'permission')){
setToastMsg('permision not satisfied');
}
else if((response.errorCode == 'others')){
setToastMsg(response.errorMessage);
}
else if(response.assets[0].fileSize > 2097152){
Alert.alert(
'Maximum image size exceeded',
'Please choose image under 2MB'
[{text: 'OK'}],
);
}
else{
Setpic(response.assets[0].base64);
}
});
}
const removeImage = () => {
Setpic('');
setToastMsg('Image removed');
}
return(
<Container>
<View>
<Avatar.Image
size= {150}
source={{ uri : 'data:image/png;base64,' + pic}}
/>
</View>
<View>
<TouchableOpacity activeOpacity={0.5} onPress={ ()=> uploadImage() }>
<Text>
Upload Image
</Text>
</TouchableOpacity>
<TouchableOpacity activeOpacity={0.5} onPress={ ()=> removeImage() }>
<Text>
Remove Image
</Text>
</TouchableOpacity>
</View>
</Container>
);
}
Can I change the code here?
const removeImage = () => {
Setpic('');
setToastMsg('Image removed');
}
or here?
<View>
<Avatar.Image
size= {150}
source={{ uri : 'data:image/png;base64,' + pic}}
/>
</View>
I'm curious where you set the default image.
If you can't change the default image, please help me to change the color.
This code is based on Android
you could try a condition if pic is empty or not.
If it is empty will be rendered. If not You Avatar will be shown.
{ pic === "" ? (
<View>
<Text>Screen if pic is empty</Text>
<View>
):
( <View>
<Avatar.Image
size= {150}
source={{ uri : 'data:image/png;base64,' + pic}}
/>
</View>
)

How do I display the numbers 0 to 10 in react native without repetition each time I click on the output?

I want the numbers 0 to 10 to be repeated only once and then start counting from 0 to 10 again.
enter image description here
import React, {Component} from 'react';
import {
StyleSheet,
Text,
View,
StatusBar,
SafeAreaView,
TouchableOpacity,
} from 'react-native';
import Ionicons from 'react-native-vector-icons/Ionicons';
export class CertificationScreen extends Component{
constructor(props) {
super(props);
}
render() {
const count = 0;
return (
<SafeAreaView style={styles.container}>
<StatusBar barStyle="light-content" />
<View style={styles.item}>
<TouchableOpacity onPress={() => this.props.navigation.navigate('Forms', {itemId: count + 1 })}>
<Ionicons style={styles.icons} name="arrow-back" size={24} color="#0064FE" />
<Text style={{fontSize: 24}}>Text</Text>
</TouchableOpacity>
</View>
</SafeAreaView>
);}
}
I researched a lot, but I could not solve this problem.
please guide me.
Yes, this is exactly what I want, to add a number by tapping TouchableOpacity. And send this data to my class component via props (itemId). But after making changes, I get this error: Too many re-renders. React limits the number of renders to prevent an infinite loop. Do you know a better way I can use it?
import React from 'react';
import {
StyleSheet,
Text,
View,
StatusBar,
SafeAreaView,
TouchableOpacity,
} from 'react-native';
import Ionicons from 'react-native-vector-icons/Ionicons';
export function CertificationScreen() {
let [counter, setCounter] = React.useState();
if (counter < 10) {
setCounter(prev => prev + 1);
} else {
setCounter(0);
}
return (
<SafeAreaView style={styles.container}>
<StatusBar barStyle="light-content" />
<View style={styles.item}>
<TouchableOpacity onPress={() =>
navigation.navigate('Forms', {itemId: setCounter })}>
<Ionicons style={styles.icons} name="arrow-back" size={24} color="#0064FE" />
<Text style={{fontSize: 24}}>Text</Text>
</TouchableOpacity>
</View>
</SafeAreaView>
);
}
enter image description here
This is exactly what I want:
let [counter, setCounter] = React.useState ();
if (counter <10) {
setCounter (prev => prev + 1);
} else {
setCounter (0);
}
After clicking on touchableOpacity, I want the data from the counter to be transferred via prop and navigation to the next page where the data is displayed in .
enter image description here
I created a snack example to better understand this issue, please let me know if there is an error in the process.
https://snack.expo.dev/#devsaeedhabibi/certification
Update:
How can I integrate Button and TouchableOpacity?
<Button title='Certification' onPress={() => {
if(counter < 10) {
setCounter(prev => prev + 1)
}else {
setCounter(1)
}
}} />
<TouchableOpacity onPress={() => navigation.navigate('Forms', {itemId: counter })}>
<Ionicons style={styles.icons} name="arrow-back" size={24} color="#0064FE" />
<Text style={{fontSize: 24, alignSelf: 'center'}}>Certification</Text>
</TouchableOpacity>
Take a look at this snack:
https://snack.expo.dev/#devsaeedhabibi/certification-2
Edit:
Using a Pressable component solved the problem.
<Pressable onPressIn={()=> {if(counter < 10) {setCounter(prev => prev + 1)}else{setCounter(1)}}}
onPress={() => navigation.navigate('Forms', {itemId: counter })}>
onPressIn:
Called immediately when a touch is engaged, before onPressOut and onPress.
onPressOut:
Called when a touch is released.
onPress:
Called after onPressOut.
This is exactly what I wanted.
Take a look at this snack:
https://snack.expo.dev/#devsaeedhabibi/certification-v3
Thank you for your attention to this matter.
I think this is what you want;
import React, {useState} from 'react'
import {View, Text, Button} from 'react-native'
const App = () => {
let [counter, setCounter] = useState(0)
return (
<View>
<Button title='counter' onPress={() => {
if (counter < 10) {
setCounter(prev => prev + 1)
} else {
setCounter(0)
}
}}/>
<Text>{counter}</Text>
</View>
)
}
export default App;

How to open Modal from another component in react-native

I have tried to open Modal from another component in react-native, but modal is not open. so please help me if have any solution. this is my code
modal.js
import React from './node_modules/react';
import { View, Text } from 'react-native';
const ProfileModal = () => {
return (
<View>
<Text>HELLO TEXT</Text>
</View>
);
}
export default ProfileModal;
----------------------------------------
header.js
import ProfileModal from './ProfileModal';
import { Image, View, TouchableOpacity, Text } from 'react-native';
import Modal from 'react-native-modal';
const openLoginPopup = () => {
return (
<TouchableOpacity onPress={() => this.openModal}>
<Text> Login </Text>
</TouchableOpacity>
)
}
const openModal = () => {
return (
<Modal isVisible={true}>
<ProfileModal />
</Modal>
)
}
Thanks,
In that case, react-native-modal provide callback onBackdropPress, onBackButtonPress to close.
You can use it like this:
const ProfileModal = ({ open, onClose }) => {
return (
<Modal isVisible={open} onBackButtonPress={onClose} onBackdropPress={onClose}>
<View>
<Text>HELLO TEXT</Text>{' '}
</View>
</Modal>
)
}
Then pass onClose function when using it:
<ProfileModal open={open} onClose={()=> setOpen(false)} />
It's like you write the content modal in modal file. So you can do it something like:
modal.js
import React, {useState} from 'react';
import { View, Text } from 'react-native';
const ProfileModal = () => {
return (
<View>
<Text>HELLO TEXT</Text>
</View>
);
}
export default ProfileModal;
----------------------------------------
header.js
import ProfileModal from './ProfileModal';
import { Image, View, TouchableOpacity, Text } from 'react-native';
import Modal from 'react-native-modal';
const Header = () => {
const [open, setOpen] = useState(false)
return (
<View>
{/* some content */}
{/* btn trigger */}
<TouchableOpacity onPress={() => setOpen(true)}>
<Text> Login </Text>
</TouchableOpacity>
<Modal isVisible={open}>
<ProfileModal />
</Modal>
</View>
)
}
or
modal.js
import React, {useState} from 'react';
import { View, Text } from 'react-native';
const ProfileModal = ({ open }) => {
return (
<Modal isVisible={open}>
<View>
<Text>HELLO TEXT</Text>
</View>
</Modal>
);
}
export default ProfileModal;
----------------------------------------
header.js
import ProfileModal from './ProfileModal';
import { Image, View, TouchableOpacity, Text } from 'react-native';
import Modal from 'react-native-modal';
const Header = () => {
const [open, setOpen] = useState(false)
return (
<View>
{/* some content */}
{/* btn trigger */}
<TouchableOpacity onPress={() => setOpen(true)}>
<Text> Login </Text>
</TouchableOpacity>
<ProfileModal open={open} />
</View>
)
}
First of all openModal method is not part of openLoginPopup so remove this before openModal method.
Just use directly like below,
const openLoginPopup = () => {
return (
<TouchableOpacity onPress={openModal}>
<Text> Login </Text>
</TouchableOpacity>
)
}
Second issue was that you also don't need arrow function in onPress event until you want to pass some parameters in openModal method. You can directly pass the method name and it will work.

How React Native to control Play/Pause Video in WebView

I am trying to play and pause video in WebView by React Native.
But when this.state.shouldPlay becomes true, the below injectedJavaScript does not work.
injectedJavaScript=
{`document.getElementsByTagName("video")[0].play();`}
Please advise how to control Video in WebView from React Native.
react-native-video cannot be used because of performance issue.
import * as React from 'react';
import { Component, useState, useEffect } from 'react';
import { Text, View, StyleSheet, Image, TouchableOpacity} from 'react-native';
import {WebView} from 'react-native-webview';
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
shouldPlay: false, // not play at default
}
}
_handlePlayAndPause = () => {
if (this.state.shouldPlay == false) {
this.setState({shouldPlay: true });
} else {
this.setState({shouldPlay: false });
};
render() {
const {shouldPlay } = this.state;
return (
<View style={styles.container}>
{ shouldPlay ?
<View>
<WebView
source={{ uri: www.url.com/sample.mp4 }}
javaScriptEnabled = {true}
injectedJavaScript=
{`document.getElementsByTagName("video")[0].play();`}
/>
</View>
:
<View>
<WebView
source={{ uri: www.url.com/sample.mp4 }}
javaScriptEnabled = {true}
injectedJavaScript=
{`document.getElementsByTagName("video")[0].pause();`}
/>
</View>
}
{ shouldPlay ?
<View>
<TouchableOpacity onPress={ this._handlePlayAndPause } >
<Ionicons name="ios-pause"/>
</TouchableOpacity>
</View>
:
<View>
<TouchableOpacity onPress={ this._handlePlayAndPause } >
<Ionicons name="ios-play-circle"/>
</TouchableOpacity>
</View>
}
</View>
)
}
}
Thank you.