Skip to content

使用方法

介绍

安卓实况图合成和分离UTS原生插件支持根据通过图片和视频参数合成实况图片,支持将实况图片分离成图片和视频文件,插件支持uniapp和uniapp x

插件说明

  • 如果您在使用插件的过程中有任何问题,可以联系作者,作者将全力协助您只用插件
  • 本文档同时提供了uniapp的用法示例和uniappx的用法示例,插件市场导入的示例项目仅为uniapp的用法示例,如果您需要uniappx的示例项目可以通过下方的链接下载示例

    https://pan.baidu.com/s/1SupTMX_KHaq7MOqgxEHtMw?pwd=1393

联系作者

关注微信公众号可联系作者

插件地址

权限

  • android.permission.INTERNET
  • android.permission.WRITE_EXTERNAL_STORAGE
  • android.permission.READ_EXTERNAL_STORAGE
  • android.permission.MANAGE_EXTERNAL_STORAGE

用法

在需要使用插件的页面加载以下代码

js
import * as module from "@/uni_modules/leven-uts-livePhoto"
js
import * as module from "@/uni_modules/leven-uts-livePhoto"

页面内容

vue
<template>
  <view>
    <!-- 实况类型 -->
    <view style="display: flex; flex-direction: row; justify-content: center; align-items: center; height: 100rpx;">
      <view style="width: 300rpx;">
        <uni-data-checkbox v-model="type" :localdata="range"></uni-data-checkbox>
      </view>
    </view>
    <!-- 合成实况-->
    <uni-card title="合成" v-if="type == 1">
      <button type="primary" @click="selectImage">选择JPEG静态图片</button>
      <view class="text-notice">{{imagePath == "" ? "未选择" : imagePath}}</view>
      <button type="primary" @click="selectVideo">选择视频文件</button>
      <view class="text-notice">{{videoPath == "" ? "未选择" : videoPath}}</view>
      <button type="primary" @click="combiner">开始合成</button>
      <view class="text-notice">提示:Google Photos 通过文件名 *MP.jpg 识别动态照片,输出文件已自动加 MP 后缀。视频需为 H.264 编码、约 3 秒时长,静态图应对应视频中某一帧。
      </view>
    </uni-card>
    <uni-card title="分离" v-if="type == 2">
      <button type="primary" @click="selectMotionPhoto">选择 MotionPhoto JPEG</button>
      <view class="text-notice">{{motionPhoto == "" ? "未选择" : motionPhoto}}</view>
      <button type="primary" @click="split">开始分离</button>
    </uni-card>
    <!-- 日志 -->
    <uni-card title="日志">
      <view style="word-wrap: break-word;">
        <text style="font-size: 12px; color: #999999;">{{logs}}</text>
      </view>
    </uni-card>
  </view>
</template>

<script>
  import * as module from "@/uni_modules/leven-uts-livePhoto"
  export default {
    data() {
      return {
        type: 1,
        range: [{
          "value": 1,
          "text": "合成"
        }, {
          "value": 2,
          "text": "分离"
        }],
        //选择的静态图片
        imagePath: "",
        //选择的视频文件
        videoPath: "",
        //实况图片
        motionPhoto: "",
        //日志信息
        logs: ""
      }
    },
    onLoad() {
      this.requestPermissions();
    },
    methods: {
      //显示消息
      showMessage(message) {
        uni.showToast({
          title: message,
          icon: "none"
        })
      },
      //分离实况图片
      split() {
        try {
          if (this.motionPhoto == "") {
            throw new Error("请选择实况图片");
          }
          module.split({
            params: {
              saveDir: "/storage/emulated/0/levenLivePhoto/split",
              path: this.motionPhoto
            },
            complete: (res) => {
              if (res.code == 0) {
                let data = res.data;
                let videoPath = data.videoPath;
                let imagePath = data.imagePath;
                let message = "分离图片路径:" + imagePath + "\r" +
                  "分离视频路径:" + videoPath + "\n";
                this.logs = message + this.logs
              }
            }
          })
        } catch (e) {
          this.showMessage(e.message)
        }
      },
      //选择实况图片
      selectMotionPhoto() {
        uni.chooseImage({
          count: 1,
          sourceType: ["album"],
          sizeType: ["original"],
          success: (res) => {
            let tempFilePaths = res.tempFilePaths;
            if (tempFilePaths.length > 0) {
              this.motionPhoto = tempFilePaths[0].replace("file://", "");
            }
          }
        })
      },
      //合成
      combiner() {
        try {
          if (this.imagePath == "") {
            throw new Error("请选择图片")
          }
          if (this.videoPath == "") {
            throw new Error("请选择视频")
          }
          module.combiner({
            params: {
              saveDir: "/storage/emulated/0/levenLivePhoto/combiner",
              imagePath: this.imagePath,
              videoPath: this.videoPath
            },
            complete: (res) => {
              console.log(res)
              if (res.code == 0) {
                let data = res.data;
                let message = "合成结果:" + data.path;
                console.log(message)
                this.logs = message + "\n" + this.logs
              }
            }
          })
        } catch (e) {
          this.showMessage(e.message)
        }
      },
      //选择视频
      selectVideo() {
        uni.chooseVideo({
          sourceType: ["album"],
          compressed: false,
          success: (res) => {
            this.videoPath = res.tempFilePath.replace("file://", "")
          }
        })
      },
      //选择图片
      selectImage() {
        uni.chooseImage({
          count: 1,
          sourceType: ["album"],
          sizeType: ["original"],
          success: (res) => {
            let tempFilePaths = res.tempFilePaths;
            if (tempFilePaths.length > 0) {
              this.imagePath = tempFilePaths[0].replace("file://", "");
            }
          }
        })
      },
      toAllFilesPermissionPage() {
        module.toAllFilesPermissionPage({
          complete: (res) => {
            if (res.code == 0) {
              let data = res.data;
              if (!data.status) {
                this.showMessage("所有文件访问权限未打开")
              } else {
                this.showMessage("权限申请完成,可以使用插件")
              }
            } else {
              this.showMessage(res.message)
            }
          }
        })
      },
      checkAllFilesPermission() {
        module.checkAllFilesPermission({
          complete: (res) => {
            if (res.code == 0) {
              let data = res.data;
              if (!data.status) {
                this.toAllFilesPermissionPage();
              } else {
                this.showMessage("权限申请完成,可以使用插件")
              }
            } else {
              this.showMessage(res.message)
            }
          }
        })
      },
      //申请插件所需权限
      requestPermissions() {
        module.requestPermissions({
          params: {
            permissions: [
              "android.permission.READ_EXTERNAL_STORAGE",
              "android.permission.WRITE_EXTERNAL_STORAGE"
            ]
          },
          complete: (res) => {
            if (res.code == 0) {
              //判断是否有所有文件访问权限
              this.checkAllFilesPermission();
            } else {
              this.showMessage(res.message)
            }
          }
        })
      },
    }
  }
</script>

<style>
  .text-notice {
    padding: 16px 0;
    color: #999999;
    word-wrap: break-word;
  }
</style>
vue
<template>
  <!-- #ifdef APP -->
  <scroll-view style="flex:1">
  <!-- #endif -->
    <view style="flex-direction: row; justify-content: center; align-items: center; height: 100rpx;">
      <rice-radio-group v-model="type" direction="row">
        <rice-radio :value="1" label="合成"></rice-radio>
        <rice-radio :value="2" label="分离"></rice-radio>
      </rice-radio-group>
    </view>
    <!-- 合成实况-->
    <lux-card title="合成" v-if="type == 1">
      <button type="primary" @click="selectImage">选择JPEG静态图片</button>
      <view class="text-notice"><text class="text-notice-info">{{imagePath == "" ? "未选择" : imagePath}}</text></view>
      <button type="primary" @click="selectVideo">选择视频文件</button>
      <view class="text-notice"><text class="text-notice-info">{{videoPath == "" ? "未选择" : videoPath}}</text></view>
      <button type="primary" @click="combiner">开始合成</button>
      <view class="text-notice">
        <text class="text-notice-info">提示:Google Photos 通过文件名 *MP.jpg 识别动态照片,输出文件已自动加 MP 后缀。视频需为 H.264 编码、约 3
          秒时长,静态图应对应视频中某一帧。</text>
      </view>
    </lux-card>
    <lux-card title="分离" v-if="type == 2">
      <button type="primary" @click="selectMotionPhoto">选择 MotionPhoto JPEG</button>
      <view class="text-notice"><text class="text-notice-info">{{motionPhoto == "" ? "未选择" : motionPhoto}}</text></view>
      <button type="primary" @click="split">开始分离</button>
    </lux-card>
    <lux-card title="日志">
      <text style="font-size: 12px; color: #999999;">{{logs}}</text>
    </lux-card>
  <!-- #ifdef APP -->
  </scroll-view>
  <!-- #endif -->
</template>

<script setup>
  import * as module from "@/uni_modules/leven-uts-livePhoto"
  import { LevenOptions, LevenResult } from "@/uni_modules/leven-uts-livePhoto"

  const type = ref(1)
  const imagePath = ref("")
  const videoPath = ref("")
  const motionPhoto = ref("")
  const logs = ref("")

  //显示消息
  function showMessage(message : string) {
    uni.showToast({
      title: message,
      icon: "none"
    })
  }

  //分离实况图片
  function split() {
    try {
      if (motionPhoto.value == "") {
        throw new Error("请选择实况图片");
      }
      module.split({
        params: {
          saveDir: "/storage/emulated/0/levenLivePhoto/split",
          path: motionPhoto.value
        },
        fail: (res : LevenResult) => {
          showMessage(res.message)
        },
        success: (res : LevenResult) => {
          if (res.code == 0) {
            let data = res.data;
            let videoPath = data.getString("videoPath")!;
            let imagePath = data.getString("imagePath")!;
            let message = "分离图片路径:" + imagePath + "\n" +
              "分离视频路径:" + videoPath + "\n";
            logs.value = message + logs.value
          }
        }
      })
    } catch (e : Error) {
      showMessage(e.message)
    }
  }

  //选择实况图片
  function selectMotionPhoto() {
    uni.chooseImage({
      count: 1,
      sourceType: ["album"],
      sizeType: ["original"],
      success: (res) => {
        let tempFilePaths = res.tempFilePaths;
        if (tempFilePaths.length > 0) {
          motionPhoto.value = tempFilePaths[0].replace("file://", "");
        }
      }
    })
  }

  //合成
  function combiner() {
    try {
      if (imagePath.value == "") {
        throw new Error("请选择图片")
      }
      if (videoPath.value == "") {
        throw new Error("请选择视频")
      }
      module.combiner({
        params: {
          saveDir: "/storage/emulated/0/levenLivePhoto/combiner",
          imagePath: imagePath.value,
          videoPath: videoPath.value
        },
        complete: (res) => {
          console.log(res)
          if (res.code == 0) {
            let data = res.data;
            let message = "合成结果:" + data.getString("path")!;
            logs.value = message + "\n" + logs.value
          }
        }
      })
    } catch (e : Error) {
      showMessage(e.message)
    }
  }

  //选择视频
  function selectVideo() {
    uni.chooseVideo({
      sourceType: ["album"],
      compressed: false,
      success: (res) => {
        videoPath.value = res.tempFilePath.replace("file://", "")
      }
    })
  }

  //选择图片
  function selectImage() {
    uni.chooseImage({
      count: 1,
      sourceType: ["album"],
      sizeType: ["original"],
      success: (res) => {
        let tempFilePaths = res.tempFilePaths;
        if (tempFilePaths.length > 0) {
          imagePath.value = tempFilePaths[0].replace("file://", "");
        }
      }
    })
  }

  function toAllFilesPermissionPage() {
    module.toAllFilesPermissionPage({
      complete: (res : LevenResult) => {
        if (res.code == 0) {
          let data = res.data;
          let status = data.getBoolean("status")!;
          if (!status) {
            showMessage("所有文件访问权限未打开")
          } else {
            showMessage("权限申请完成,可以使用插件")
          }
        } else {
          showMessage(res.message)
        }
      }
    } as LevenOptions)
  }

  function checkAllFilesPermission() {
    module.checkAllFilesPermission({
      complete: (res : LevenResult) => {
        if (res.code == 0) {
          let data = res.data;
          let status = data.getBoolean("status")!;
          if (!status) {
            toAllFilesPermissionPage();
          } else {
            showMessage("权限申请完成,可以使用插件")
          }
        } else {
          showMessage(res.message)
        }
      }
    } as LevenOptions)
  }

  //申请插件所需权限
  function requestPermissions() {
    module.requestPermissions({
      params: {
        permissions: [
          "android.permission.READ_EXTERNAL_STORAGE",
          "android.permission.WRITE_EXTERNAL_STORAGE"
        ]
      },
      complete: (res : LevenResult) => {
        if (res.code == 0) {
          //判断是否有所有文件访问权限
          checkAllFilesPermission();
        } else {
          showMessage(res.message)
        }
      }
    } as LevenOptions)
  }

  onMounted(() => {
    nextTick(() => {
      requestPermissions();
    })
  })
</script>

<style>
  .text-notice {
    padding: 16px 0;
  }

  .text-notice-info {
    color: #999999;
    font-size: 14px;
  }
</style>