1. 程式人生 > >Vue.js 2.0 移動端拍照壓縮圖片預覽及上傳

Vue.js 2.0 移動端拍照壓縮圖片預覽及上傳

在學習和使用Vue.js 2.0 的過程中遇到不少不一樣的地方,本來移動端開發H5應用,準備將mui框架和Vue.js+vue-router+vuex 全家桶結合起來使用,但是在拍照上傳的實現過程中遇到了無法呼叫plus的H5+介面的問題,所以最後拍照上傳功能還是使用input file方式裡解決的。但是內心還是不甘心的,由於專案進度推進,迭代版本,所以不得不放棄,後續可能我將此功能使用呼叫H5+介面實現。

首先我來講我實現這個拍照預覽壓縮上傳的思路,準確的說應該是拍照或選擇圖片壓縮之後預覽及上傳這個流程。每次拍照或選擇一張圖片-然後壓縮圖片-預覽上傳。上傳圖片壓縮外掛是這個外掛的使用說明可以去看wiki,基本原理是通過canvas渲染圖片,再通過 toDataURL

 方法壓縮儲存為base64字串(能夠編譯為jpg格式的圖片),壓縮效果很不錯,ios拍照2MB多壓縮下來大概是60-80kb左右,失真不是太嚴重,但是對我的專案來說圖片清晰可見就好,我貼的程式碼裡面也會有使用的演示。



<template>
	<h5 class="content-header">圖片列表</h5>
	<div class="image-list">
		<div class="list-default-img" v-show="isPhoto" @click.stop="addPic">
			<img src="./images/icon_photo.png" />
			<span>請選擇或者拍照上傳照片</span>
			<input type="file" accept="image/jpeg,image/jpg,image/png" capture="camera" @change="onFileChange"  style="display: none;">
		</div>
		<ul class="list-ul" v-show="!isPhoto">
			<li class="list-li" v-for="(iu, index) in imgUrls">
				<a class="list-link" @click='previewImage(iu)'>
					<img :src="iu">
				</a>
				<span class="list-img-close" @click='delImage(index)'></span>
			</li>
			<li class="list-li-add">
				<span class="add-img" @click.stop="addPic"></span>
			</li>
		</ul>
	</div>
    <div class="add-preview" v-show="isPreview" @click="closePreview">
		<img :src="previewImg">
	</div>
	
</template>

<script>

	export default {
		data: function () {
			return {
				imgUrls: [],
				urlArr: [],
				isPhoto: true,
				btnTitle: '',
				isModify: false,
				previewImg:'',
				isPreview: false
			}
		},
		watch: {
			imgUrls: 'toggleAddPic'
		},
		methods: {
			toggleAddPic: function() {
				let vm = this;
				if(vm.imgUrls.length >= 1) {
					vm.isPhoto = false;
				} else {
					vm.isPhoto = true;
				}
			},
			addPic: function(e) {
				let vm = this;
				$('input[type=file]').trigger('click');
				return false;
			},
			onFileChange: function(e) {
				var files = e.target.files || e.dataTransfer.files;
				if(!files.length) return;
				this.createImage(files, e);
			},
			createImage: function(file, e) {
				let vm = this;
				lrz(file[0], { width: 480 }).then(function(rst) {
					vm.imgUrls.push(rst.base64);
					return rst;
				}).always(function() {
				// 清空檔案上傳控制元件的值
				e.target.value = null;
			});
			},
			delImage: function(index) {
				let vm = this;
				let btnArray = ['取消', '確定'];
				mui.confirm('確定刪除該圖片?','提示', btnArray, function(e) {
					if (e.index == 1) {
						vm.imgUrls.splice(index, 1);
					}
				})

			},
			previewImage: function(url){
				let vm = this;
				vm.isPreview = true;
				vm.previewImg = url;
			},
			closePreview: function(){
				let vm = this;
				vm.isPreview = false;
				vm.previewImg = "";
			},
			saveImage: function(){
				let vm = this;
				let urlArr = [],
				imgUrls = this.imgUrls;

				for(let i = 0; i < imgUrls.length; i++) {
					if(imgUrls[i].indexOf('file') == -1) {
						urlArr.push(imgUrls[i].split(',')[1]);
					} else {
						urlArr.push(imgUrls[i]);
					}
				}

				//資料傳輸操作
			}
		}
	}
	
</script>

1.點選拍照或選擇圖片 addPic

在vue.js中出發拍照和選擇圖片是頻繁操作行為,每次只能拍照或選擇一張圖片,可以拍多張上傳,使用給click事件加上.stop的修飾符,.stop - 呼叫 event.stopPropagation() ,是為了停止冒泡。accept是為了規定通過檔案上傳來提交的檔案的型別,capture是webApp中捕獲到系統預設的裝置,camera--照相機;camcorder--攝像機;microphone--錄音。

在觸發拍照行為的時候繫結change事件 onFileChange 獲取file檔案物件,然後呼叫lrz方法壓縮圖片,在imgUrls陣列中新增基於base64格式的圖片。

lrz(file[0], { width: 480 }).then(function(rst) {
					vm.imgUrls.push(rst.base64);
					return rst;
				}).always(function() {
				// 清空檔案上傳控制元件的值
				e.target.value = null;
			});
lrz(file, [options]);

file: 通過 input:file 得到的檔案,或者直接傳入圖片路徑。

[options] :這個引數允許忽略。

width {Number} 圖片最大不超過的寬度,預設為原圖寬度,高度不設時會適應寬度;
    height {Number} 同上;
    quality {Number} 圖片壓縮質量,取值 0 - 1,預設為0.7;
    fieldName {String} 後端接收的欄位名,預設:file;

返回結果是一個promise物件,有then()、catch()、always三個方法。

then(rst):

rst.formData 後端可處理的資料;
    rst.file 壓縮後的file物件(預設已經丟在rst.formData有一份了),需要注意的是如果壓縮率太低的話,這個會是原始的file物件;
    rst.fileLen 生成後的圖片的大小,後端可以通過此值來校驗是否傳輸完整;
    rst.base64 生成後的圖片base64,後端可以處理此字串為圖片,也直接用於img.src = base64;
    rst.base64Len 生成後的base64的大小,後端可以通過此值來校驗是否傳輸完整 (如果採用base64上傳方式);
    rst.origin 也就是原始的file物件,裡面存了一些原始檔案的資訊,例如大小,日期等;

catch(err) 、always() 。

注意:由於我們可能持續點選拍照上傳圖片,使用在alway回撥函式裡面必須清空上傳控制的值。

// 清空檔案上傳控制元件的值
 e.target.value = null;

2. 點選拍第一張照片和顯示預覽以及繼續拍照的DOM顯示  isPhoto

預設 isPhoto 為true,隱藏繼續拍照的DOM顯示,toggleAddPic 監聽當前選中imgUrls陣列長度,轉換 isPhoto 的布林值若有一張及以上的圖片設定 isPhoto 為false, 則隱藏點選拍第一張照片DOM,顯示繼續拍照的DOM;若沒有圖片,則隱藏繼續拍照的DOM,顯示擊拍第一張照片DOM。

3. 刪除已選擇的壓縮圖片 delImage

根據陣列對應的下標,在imgUrls中刪除對應的圖片資料。

delImage: function(index) {
				let vm = this;
				let btnArray = ['取消', '確定'];
				mui.confirm('確定刪除該圖片?','提示', btnArray, function(e) {
					if (e.index == 1) {
						vm.imgUrls.splice(index, 1);
					}
				})

			}

4. 大圖預覽已經被壓縮的圖片及關閉大圖預覽  isPreview previewImage closePreview

在這裡大圖預覽就是將base64格式的圖片直接放進預覽DOM的img src中放大展示,點選圖片自身關閉預覽,清空img src資源。

5. 對base64圖片傳輸前的處理 saveImage

saveImage: function(){
				let vm = this;
				let urlArr = [],
				imgUrls = this.imgUrls;

				for(let i = 0; i < imgUrls.length; i++) {
					if(imgUrls[i].indexOf('file') == -1) {
						urlArr.push(imgUrls[i].split(',')[1]);
					} else {
						urlArr.push(imgUrls[i]);
					}
				}

				//資料傳輸操作
			}

我壓縮成base64字串是“data:image/jpeg;base64,~~”的字串,為了後端好處理,我這裡為了將編輯時候後臺返回的圖片url區別開來,將“data:image/jpeg;base64,"擷取掉,只傳遞給後端逗號後面的base64字串。

注意:後端接收到我傳遞的base64字串陣列的時候,發現字元經如果被urlencode後標準的base64中的/、 +會被轉成%xx,後端在將base64字串處理成圖片時,需要將特殊字元過濾掉。

[HttpPost]
        public ActionResult MUploadImgBase64Str(string base64str)
        {
            try
            {
                var imgData = base64str;
                //過濾特殊字元即可   
                string dummyData = imgData.Trim().Replace("%", "").Replace(",", "").Replace(" ", "+");
                if (dummyData.Length % 4 > 0)
                {
                    dummyData = dummyData.PadRight(dummyData.Length + 4 - dummyData.Length % 4, '=');
                }
                byte[] byteArray = Convert.FromBase64String(dummyData);
                using (System.IO.MemoryStream ms = new System.IO.MemoryStream(byteArray))
                {
                    var img = System.Drawing.Image.FromStream(ms);

                    var path = "~/Content/UploadFiles/mobile/";
                    var uploadpath = Server.MapPath(path);
                    if (!Directory.Exists(uploadpath))
                    {
                        Directory.CreateDirectory(uploadpath);
                    }
                    var saveName = uploadpath + “stoneniqiu” + ".jpg";
                    img.Save(saveName);
                    return Json(saveName);
                }
            }
            catch (Exception e)
            {
                return Json(e.Message);

            }
        }

相關推薦

Vue.js 2.0 移動拍照壓縮圖片

在學習和使用Vue.js 2.0 的過程中遇到不少不一樣的地方,本來移動端開發H5應用,準備將mui框架和Vue.js+vue-router+vuex 全家桶結合起來使用,但是在拍照上傳的實現過程中遇到了無法呼叫plus的H5+介面的問題,所以最後拍照上傳功能還是使用input file方式裡解決的。但是

移動HTML5 檔案

本文主要介紹使用HTML5 圖片上傳及上傳前的預覽。本人是做PHP後端的,由於前端有時也需要自己寫,有空就研究了下圖片上傳預覽,寫的都是原生程式碼,廢話不多說,直接上程式碼。 前端程式碼 <!DOCTYPE html> <html lang

js圖片,前端修改檔名

<!doctype html><html lang="en"><head>    <meta charset="UTF-8">    <title>Demo</title>   <!--  IE需要

vue.js 結合corodva 移動 附件以及圖片拍照

1.html 點選事件觸發方法呼叫cordova中的getPicture處理  _this.pictureSource=navigator.camera.PictureSourceType; _this.destinationType=navigator.camera.De

vue.js 2.0中使用less

webpack b- red sta pla pack block pre shee 說明,使用的是npm init webpack 項目名方式創建的項目,無需手動配置webpack 1.安裝less依賴 npm install less less-loader --s

Vue.js 2.0 由淺入深,第一天 day01

vue.js vue vuex axios 湯小洋 湯老師 ### Vue.js 五天 *湯小洋*## 一、 Vue.js簡介### 1. Vue.js是什麽 **Vue.js**也稱為Vue,讀音/vju:/,類似view,錯誤讀音v-u-e 版本:v1.0 v2.0 + 是一

node+webpack環境搭建 vue.js 2.0 基礎學習筆記

build tao 2.0 png 模板 gis mage tps 環境 npm install -g vue //全局安裝vue npm install -g webpack //全局安裝webpack npm install -g vue-cli

vue.js 2.0 官方文檔學習筆記 —— 01. vue 介紹

lan fun 數據 特性 sem https 代碼 guide pos 這是我的vue.js 2.0的學習筆記,采取了將官方文檔中的代碼集中到一個文件的形式。目的是保存下來,方便自己查閱。 !官方文檔:https://cn.vuejs.org/v2/guide/ 01.

vue js 2.0

七億少女的劫丨 學習Vue js 2.0 第一天-1 學習Vue js 2.0 第一天-1 webstorm 引用 Vue js 2.0 CDN 使用 1.v-bind 2.v-model 3.template標籤生成 <!DOCTYP

Vue.js 2.0之全家桶系列(vuevue-router、axios、vuex)

get set style pack inf del 常用指令 百度網盤 大綱 基於Vue.js 2.3版本, 全面講解Vue.js的教學視頻,讓你少走彎路,直達技術前沿!包含Vue.js全家桶(vue.js、vue-router、axios、vuex、vue-cli、w

Vue.js 2.0 教程精華梳理(一) 基礎

Vue.js 第一部分 Vue.js 介紹 Vue.js(讀音 /vjuː/, 類似於 view) 是一套構建使用者介面的 漸進式框架。與其他重量級框架不同的是,Vue 採用自底向上增量開發的設計。Vue 的核心庫只關注檢視層,並且非常容易學習,非常容易與其

基於 Vue.js 2.0 酷炫自適應背景視訊登入頁面的設計

本文講述如何實現擁有酷炫背景視訊的登入頁面,瀏覽器視窗隨意拉伸,背景視訊及前景登入元件均能完美適配,背景視訊可始終鋪滿視窗,前景元件始終居中,視訊的內容始終得到最大限度的保留,可以得到最好的視覺效果。並且基於 Vue.js 2.0 全家桶。具體效果如下圖所示:

vue.js 2.0 關於ref--繫結dom物件並獲取

v-ref、v-el 棄用 統一使用ref屬性為元素或元件新增標記,然後通過this.$refs獲取。 開始我用: <div class="menu-wrapper" ref="menu-wrapper"> 來繫結dom物

Vue.js 2.0以後模擬前後臺數據互動

Webstorm開發Vue專案模擬資料的前後臺互動 1、使用命令進入專案所在目錄,載入vue-resource(一定要放在專案所在的目錄下) cd  H:\vue\demo   ###這個是我的專案所在的目錄 npm install&nbs

vue.js 2.0父子元件學習入門套路

前面已經瞭解過vue的元件化開發了,現在來了解一下父子元件。 先來2個子元件 myname.vue 內容如下: <template> <div id="myname">我的名字是{{name}}</div>

Vue.js 2.0之全家桶系列視訊課程(vuevue-router、axios、vuex)-湯小洋-專題視訊課程...

Vue.js 2.0之全家桶系列視訊課程(vue、vue-router、axios、vuex)—1048人已學習 課程介紹        基於新的Vue.js 2.3版本, 目前新全的Vue.js教學視訊,讓你少走彎路,直達技術前沿! 1. 包含Vue.js全家桶(vue.j

Vue.js 2.0 學習路線

從今天開始學習一些關於前端的框架,找到了一篇很不錯的vue.js學習路線介紹,分享一下   最近VueJs確實火了一把,自從Vue2.0釋出後,Vue就成了前端領域的熱門話題,github也突破了三萬的star,那麼對於新手來說,如何高效快速的學習Vu

基於vue.js 2.0,不使用webpack的nodejs服務,只在瀏覽器單獨使用在Element UI的Tree樹形控制元件

Vue.js(讀音 /vjuː/,類似於 view) 是一套構建使用者介面的漸進式框架。與其他重量級框架不同的是,Vue 採用自底向上增量開發的設計。Vue 的核心庫只關注檢視層,它不僅易於上手,還便於與第三方庫或既有專案整合。另一方面,當與單檔案元件和 Vue

Vue.js 2.0之全家桶系列視訊課程——筆記(五)

一、 準備工作 ###1. 初始化專案 vue init webpack itany cd itany cnpm install cnpm install less less-loader -D

vue.js初學—DIY移動輸入鍵盤

在專案開發的過程中呢,我們需要使用者輸入一些東西,但又不願意讓使用者隨意的進行輸入,因而可能會選擇使用一個自定義的輸入法,來限制使用者輸入的東西,那麼接下來,我們就通過一個簡單的例子,來看看,移動端網頁中,輸入法該怎麼去設定。這裡我們依舊使用了我們的老朋友Vue,來進行實現