在Vue中实现app拍照-选取本地图库-图片上传成功后预览

基于Vue和uni-app实现手机app的功能实现和打包。拍照功能和选取本地图片使用的是HTML5的API 实现。

我为测试这个功能使用node写了个本地服务器,对于手机调试,可以通过连接同一个无线网访问对应的地址进行测试。

选取本地图片

Gallery模块管理系统相册,支持从相册中选择图片或视频文件、保存图片或视频文件到相册等功能。通过plus.gallery获取相册管理对象。

gallery有两个方法: pick 和 save 通过名称可知一个是选择图库文件一个是保存到图库中,这里只使用了 pick 方法。

void plus.gallery.pick(successCB, errorCB, options);
// 从相册中选择图片 
function galleryImg() {
	// 从相册中选择图片
	console.log("从相册中选择图片:");
    plus.gallery.pick( function(path){
      // 返回的路径等会上传的时候要用
    	console.log(path);
    }, function ( e ) {
      // 失败的回调函数
    	console.log( "取消选择图片" );
    }, {
      // 图片获取的选项
      
      // 图库文件过滤选项
      filter:"image",
      
    } );
}
// 从相册中选择多张图片 
function galleryImgs(){
	// 从相册中选择图片
	console.log("从相册中选择多张图片:");
    plus.gallery.pick( function(e){
    	for(var i in e.files){
	    	console.log(e.files[i]);
    	}
    }, function ( e ) {
    	console.log( "取消选择图片" );
    },{
      filter:"image",
      // 是否可以多选
      multiple:true,
      // 设定最多可选取数量
      maximum:3,
      // 是否使用系统相册文件选择界面
      system:false,
      // 当超过设定的选取数量触发的事件
      onmaxed:function(){
        plus.nativeUI.alert('最多只能选择3张图片');
        }
    });
}
  // 获取相册图片
  // 从相册中选择多张图片
  galleryImgs(url, imgMaxNum) {
	// 从相册中选择图片
	console.log('从相册中选择多张图片:')
	plus.gallery.pick(function (e) {
		// 成功回调
		console.log(e)
		// 如果选取成功则执行上传功能
		// 创建任务
		// 返回以upload对象
		let task = plus.uploader.createUpload(url,
		  {
			method: 'POST',
			// 上传任务每次上传的文件块大小(仅在支持断点续传的服务有效)
			// 数值类型,单位为Byte(字节),默认值为102400,若设置值小于等于0则表示不分块上传
			blocksize: 10000000000000000000000000,
			// 上传任务的优先级,数值类型,数值越大优先级越高,默认优先级值为0。
			priority: 100,
			// 上传任务超时时间
			timeout: 51000
		  },
		  // 完成函数,成功失败都会调用次函数
		  function (t, status) {
			// 上传完成
			if (status == 200) {
			  // 上传成功返回url
			  alert('Upload success: ' + t.url)
			} else {
			  alert('Upload failed: ' + status)
			}
		  }
		)

		// 遍历添加文件
		for (var i in e.files) {
		  // 使用图片选取后返回的文件路径
		  // param 1添加上传文件的路径
		  // param2  可通过此参数设置上传任务属性,如文件标识、文件名称、文件类型等, key如果重复会导致上传失败
		  // 函数返回一个布尔值,代表添加文件成功与否
		  task.addFile(e.files[i], { key: 'ducha' + i + Math.random() * 10 })
		}

		// 添加上传数据
		if (imgType !== undefined) {
		  task.addData('IMG_TYPE', imgType)
		}
		task.start()

	  }, function (e) {
		// 失败回调
		console.log('取消选择图片')
	  },
	  {
		// options
		filter: 'image',
		// 多选
		multiple: true,
		// 是否调用手机终端自带的相册页面
		system: true,
		maximum: imgMaxNum || '',
		onmaxed: function () {
		  plus.nativeUI.alert('最多只能选择' + imgMaxNum + '张图片')
		}
	  })
  }

拍照

camera

Camera模块管理设备的摄像头,可用于拍照、摄像操作,通过plus.camera获取摄像头管理对象。

它具有一个方法 getCamera

// 返回一个摄像头管理对象,只有需要拍照和录像功能需要先获取此对象才行

// index 表示摄像头,1默认摄像头(主摄像头),2表示副摄像头

Camera =  plus.camera.getCamera( index )

Camera 摄像头管理对象具有三个方法,分别是获取拍照功能 captureImage 和获取录像功能 startVideoCaputer  和停止录像功能 stopVideoCaputer 。
   我们使用 captureImage 方法进行拍照功能的实现。

功能具有拍照,压缩,上传功能


/**
 *
 * @param {上传的url} url
 * @param {上传后得到的回调} callback
 * @param {上传失败的回调} errBack
 */
function camera(url, callback, errBack) {
  // 获取到camera
  let cmr = plus.camera.getCamera();
  // 调用cmr的captureImage方法进行拍照功能的调用
  cmr.captureImage(function() {
    // 成功回调
    // 通过resolveFileSystemURL 获取真实地址
    plus.io.resolveLocalFileSystemURL(e, function(entry) {
      let imgUrl = entry.toLocalURL();
      let imgName = new Date().valueOf();
      let imgSuffix = imgUrl.substr(e.lastIndexOf('/') + 1);

      // 进行压缩
      plus.zip.compressImage(
        {
          src: imgUrl,
          // 压缩后图片的路径
          dst: '_doc/' + imgName + imgSuffix,
          overwrite: true,
          quality: 50,
          // 高度可以根据自己的需求设定
          height: '100px'
        },
        function(event) {
          // 压缩成功回调
          let target = event.target;
          // 调用上传组件
          upload(url, target, callback, errBack);
        },
        function() {
          // 失败回调
        }
      );
    });
  });
}

/**
 *
 * @param {上传的url} url
 * @param {用来上传的图片地址} target
 * @param {上传后得到的回调} callback
 * @param {上传失败的回调} errBack
 */
function upload(url, target, callback, errBack) {
  var task = plus.uploader.createUpload(
    url,
    {
      method: 'POST',
      blocksize: 888888,
      priority: 100,
      timeout: 51000
    },
    function(data, status) {
      // 上传完成
      if (status === 200) {
        return callback(data.responseText);
      } else {
        errBack(data);
      }
    }
  );
  task.addFile(target, {
    key: 'a' + Math.random() * 10
  });
  task.start();
}

图片预览功能

使用vue-image-swiper实现一个预览页面

<template>
  <div class="camera">
    <my-header :title="title" class="xxxxx"></my-header>
    <div class='camera-list'>
      <ul class="show-list">
        <li
          :key="index"
          @click="preview(index)"
          class='add-btn'
          v-for="(l, index) in imageUrl">
          <img :src="l" alt="">
        </li>
        <li
          class="add-btn"
          @click="openGetImage"
        >
          <van-icon name="plus"/>
        </li>
      </ul>
    </div>
    <actionsheet ref="actionsheet" :data="actionsheetData" @change="actionsheetChange" class="select"></actionsheet>
  </div>
</template>

<script>
  import MyHeader from 'my-header'
  import Actionsheet from 'actionsheet'
  import {camera, pick} from 'getImages'

  export default {
    name: 'camera',
    data() {
      return {
        title: '图片上传',
        imageUrl: [],
        actionsheetData: [
          {
            'id': '1',
            'name': '拍照'
          },
          {
            'id': '2',
            'name': '相册'
          }
        ],
      }
    },
    methods: {
      preview(index) {
        this.$imagePreview({
          images: this.images,
          index: index
        })
      },
      openGetImage() {
        this.$refs.actionsheet.show()
      },
      // 弹出标签
      actionsheetChange(item) {
        if (item.id === '1') {
          this.getImage()
        } else if (item.id === '2') {
          this.appendByGallery()
        }
      },
      addImg(data) {
        let imgs = data.IMG_URL.split(',')
        for (let i in imgs) {
          imgs[i] = wwwBase + imgs[i]
        }
        let ids = data.IMG_ID.split(',')
        this.imageId = this.imageId + ',' + ids
        // this.SaveImgId(this.imageId)
        this.SaveImgId('3333')
        // this.formDataShow.IMG_ID = this.formDataShow.IMG_ID.concat(ids)
        // this.formDataShow.IMG_URL = this.formDataShow.IMG_URL.concat(imgs)
        // this.formData.IMG_ID = this.formDataShow.IMG_ID.join()
        this.imageUrl = [...this.imageUrl, imgs]
      },
      // 上传失败的统一错误回调
      errorBack(err) {
        alert(err)
      },
      getImage() {
        // 拍照
        let that = this
        camera(url, function (res) {
          res = JSON.parse(res)
            that.addImg(res.data)
        }, this.errorBack, '1')
      },
      appendByGallery() {
        // 相册
        let that = this
        pick(url, function (res) {
          res = JSON.parse(res)
          that.addImg(res.data)
        }, this.errorBack, '1')
      }
    },
    components: {
      MyHeader,
      Actionsheet
    }
  }
</script>

关于后端的服务器和整体项目

全部会上传到github上,可以直接clone下来进行查看。

原文地址:https://www.cnblogs.com/daixixi/p/12298016.html