Search docs/

使用相机拍照

接下来是有趣的部分 - 使用Capacitor Camera API 调用设备的相机,为你的应用添加拍照功能。 我们以此构建Web,然后做小的调整,使其能够在移动设备 (iOS和Android) 上面运行。

为此,我们将创建一个与Vue的Composition API 配对的独立合成函数,以管理照片库的照片。

If you are not familiar with Vue's Composition API, Why Composition API? from the official Vue docs is a good resource to start with.

Create a new file at src/composables/usePhotoGallery.ts and open it up.

We will start by importing the various utilities we will use from Vue core and Capacitor:

import { ref, onMounted, watch } from 'vue';
import { Plugins, CameraResultType, CameraSource, CameraPhoto, 
Capacitor, FilesystemDirectory } from "@capacitor/core";
CopyCopied

Next, create a function named usePhotoGallery:

export function usePhotoGallery() {
  const { Camera } = Plugins;

  const takePhoto = async () => {
    const cameraPhoto = await Camera.getPhoto({
      resultType: CameraResultType.Uri,
      source: CameraSource.Camera,
      quality: 100
    });
  };

  return {
    takePhoto
  };
}
CopyCopied

Our usePhotoGallery function exposes a method called takePhoto, which in turn calls the Capacitor Camera API's getPhoto method.

Notice the magic here: there's no platform-specific code (web, iOS, or Android)! The Capacitor Camera plugin abstracts that away for us, leaving just one method call - getPhoto() - that will open up the device's camera and allow us to take photos.

The last step we need to take is to use the new function from the Tab2 page. Go back to Tab2.vue and import it:

import { usePhotoGallery } from '@/composables/usePhotoGallery';
CopyCopied

Next, within the default export, add a setup method, part of the Composition API. Destructure the takePhoto function from usePhotoGallery, then return it:

<script lang="ts">
import { camera, trash, close } from 'ionicons/icons';
import { IonPage, IonHeader, IonFab, IonFabButton, IonIcon, 
         IonToolbar, IonTitle, IonContent, IonGrid, IonRow, 
         IonCol, IonImg } from '@ionic/vue';
import { usePhotoGallery } from '@/composables/usePhotoGallery';

export default  {
  name: 'Tab2',
  components: { IonPage, IonHeader, IonFab, IonFabButton, IonIcon, 
         IonToolbar, IonTitle, IonContent, IonGrid, IonRow, 
         IonCol, IonImg },
  setup() {
    const { takePhoto } = usePhotoGallery();

    return {
      takePhoto,
      camera, trash, close
    }
  }
}
</script>
CopyCopied

Save the file, and if you’re not already, restart the development server in your browser by running ionic serve. On the Photo Gallery tab, click the Camera button. If your computer has a webcam of any sort, a modal window appears. Take a selfie!

Camera API on the web

(Your selfie is probably much better than mine)

After taking a photo, it disappears right away. We still need to display it within our app and save it for future access.

Displaying Photos

First we will create a new type to define our Photo, which will hold specific metadata. Add the following Photo interface to the usePhotoGallery.ts file, somewhere outside of the main function:

export interface Photo {
  filepath: string;
  webviewPath?: string;
}
CopyCopied

Back at the top of the function (right after referencing the Capacitor Camera plugin), define an array so we can store each photo captured with the Camera. Make it a reactive variable using Vue's ref function.

const photos = ref<Photo[]>([]);
CopyCopied

When the camera is done taking a picture, the resulting CameraPhoto returned from Capacitor will be added to the photos array. Update the takePhoto method, adding this code after the Camera.getPhoto line:

const fileName = new Date().getTime() + '.jpeg';
const savedFileImage = {
  filepath: fileName,
  webviewPath: cameraPhoto.webPath
};

photos.value = [savedFileImage, ...photos.value];
CopyCopied

Next, update the return statement to include the photos array:

return {
  photos,
  takePhoto
};
CopyCopied

Back in the Tab2 component, update the import statement to include the Photo interface:

import { usePhotoGallery, Photo } from '@/composables/usePhotoGallery';
CopyCopied

Then, get access to the photos array:

const { photos, takePhoto } = usePhotoGallery();
CopyCopied

Last, add photos to setup() return:

return {
  photos,
  takePhoto,
  camera, trash, close
}
CopyCopied

With the photo(s) stored into the main array we can now display the images on the screen. Add a Grid component so that each photo will display nicely as they are added to the gallery, and loop through each photo in the Photos array, adding an Image component (<ion-img>) for each. Point the src (source) to the photo's path:

<ion-content>
  <ion-grid>
    <ion-row>
      <ion-col size="6" :key="photo" v-for="photo in photos">
        <ion-img :src="photo.webviewPath"></ion-img>
      </ion-col>
    </ion-row>
  </ion-grid>

  <!-- <ion-fab> markup  -->
</ion-content>
CopyCopied

Save all files. Within the web browser, click the Camera button and take another photo. This time, the photo is displayed in the Photo Gallery!

Up next, we’ll add support for saving the photos to the filesystem, so they can be retrieved and displayed in our app at a later time.

Previous
你的第一个 App
Next
保存照片到文件系统中