why expo-camera alongwith vue-native is not capturing picture?

145 Views Asked by At

I am trying to learn vue-native and creating a practice application to use camera and capture an image. In documentation they are using some ref to assign camera to it but I do not know the exact method to pass ref in vue-native. I have done little homework and found this issue on git but it also didn;t help.

Ref: https://github.com/GeekyAnts/vue-native-core/issues/88

Doc (vue-native): https://vue-native.io/docs/device-apis.html#Camera

Doc (expo-camera): https://docs.expo.io/versions/latest/sdk/camera/#takepictureasync

The code snippet is:

<template>
  <view class="container">
    <camera 
      class="camera" 
      :type=type
      ref="camera"  
    >
      <view class="camera-view-1">
          <view class="camera-view-2">
            <view class="camera-view-3">
              <touchable-opacity 
                class="camera-touchable-opacity"
                :on-press="_takePicture"
              >
                <text style="color: #FF0000">Capture</text>
              </touchable-opacity>
            </view>
          </view>
        </view>    
    </camera>
    <view>
      <touchable-opacity
        :on-press="_changeCamera">
        <text class="change-cam"> Change Camera </text>
      </touchable-opacity>
      <button title="Go to home screen" @press="goToHomeScreen"></button>    
    </view>
  </view>
</template>

<script>
import * as Permissions from 'expo-permissions';
import { Camera } from 'expo-camera';        
export default {
  data: function() {
    return {
      hasCameraPermission: false,
      type: Camera.Constants.Type.back,
      img: '',
    };
  },
  props: {
    navigation: { type: Object }
  },
  methods: {
    goToHomeScreen() {
      this.navigation.navigate("Home");
    },
    _changeCamera: function() {
        this.type = (this.type === Camera.Constants.Type.back ? Camera.Constants.Type.front : Camera.Constants.Type.back);
    },
    _takePicture: async function() {
      if(!camera) return;
      const photo = await camera.takePictureAsync();
    }
  },
  mounted: function() {
    Permissions.askAsync(Permissions.CAMERA)
      .then(status => {
        hasCameraPermission = status.status == "granted" ? true : false;
      }).catch((err)=>{
          console.log(err);
      });
  },
  components: { Camera },
};
</script>

<style>
.container, .camera {
  flex: 1;
}

.change-cam {
  color: #FF0000;
  text-align: center;
}
</style>

When I click on the capture button, I am getting an error that camera is not defined. I think I am not using ref correctly. can someone suggest the correct way to use it in vue-native? Thanks

2

There are 2 best solutions below

1
YOUSAF KHAN On
#In which code open camera and take picture# 
#Note: npm/yarn install expo-permissions#
#npm/yarn install expo-camera#    
    <template>
      <view class="container">
        <camera
          class="container"
          :type="this.type"
          ref="this.camera"
          v-if="!!myPreviewImg.uri === false"
        />
        <touchable-opacity
          class="camera-touchable-opacity"
          :on-press="capturePic"
          :disabled="!readyCapture"
          v-if="!!myPreviewImg.uri === false"
        >
          <text :style="{ color: 'white', fontSize: 20, backgroundColor: 'blue' }"
            >Take Picture</text
          >
        </touchable-opacity>
    
        <View v-if="!!myPreviewImg.uri === true">
          <Image style="width: 100%; height: 95%" :source="myPreviewImg"> </Image>
          <touchable-opacity class="camera-touchable-opacity" :on-press="close">
            <text :style="{ color: 'white', fontSize: 20, backgroundColor: 'blue' }"
              >Close</text
            >
          </touchable-opacity>
        </View>
      </view>
    </template>
    <script>
    import * as Permissions from "expo-permissions";
    import { Camera } from "expo-camera";
    
    export default {
      data: function () {
        return {
          hasCameraPermission: false,
          type: Camera.Constants.Type.back,
          isPreview: false,
          ref: null,
          cameraRef: "",
          readyCapture: false,
          myPreviewImg: {
            uri: false,
          },
        };
      },
      mounted: function () {
        this.cameraPic();
      },
      methods: {
        capturePic: async function () {
          let data = await this.$refs["this.camera"].takePictureAsync();
          console.log("photo", data);
          this.myPreviewImg = {
            uri: data.uri,
          };
          this.readyCapture = true;
        },
        cameraPic: async function () {
          let { status } = await Camera.requestPermissionsAsync();
          if (status === "granted") {
            console.log("Permission to access location was denied");
            this.hasCameraPermission = status == "granted" ? true : false;
            console.log(this.hasCameraPermission);
            this.readyCapture = true;
            return;
          }
        },
        close: function () {
          this.myPreviewImg = {
            uri: false,
          };
        },
      },
      components: { Camera },
    };
    </script>
    <style>
    .container {
      flex: 1;
    }
    .text-color-primary {
      color: blue;
    }
    </style>
0
onestepp On

You can refer your camera as this.$refs.camera in your method, since you defined the reference on the element as ref="camera" in your code..

The capture function will be this.$refs.camera.takePictureAsync()

In your code

_takePicture: async function() {
      if(!camera) return;
      const photo = await this.$refs.camera.takePictureAsync();
    }