基於Vue和uni-app實現手機app的功能實現和打包。拍照功能和選取本地圖片使用的是HTML5的API 實現。
我為測試這個功能使用node寫了個本地服務器,對於手機調試,可以通過連接同一個無線網訪問對應的地址進行測試。
選取本地圖片
gallery
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下來進行查看。