<template><div class="me-detail"><m-hbar title="个人笔记"/><div class="detail-title">个人总结</div><p v-if="vpersonalNotes.notesContext">{{vpersonalNotes.notesContext}}</p><textarea class="note-textarea"  v-else v-model="notesContext"></textarea><div class="detail-title">图片</div><ul class="img-list" v-if="vpersonalNotes.notesContext"><li class="img-list-li" v-for="i in accessoryInfo" :key="i.fileBh"><img :src="picUrl + i.fileBh" alt=""></li></ul><ul class="img-list" v-else><li class="img-list-li" v-for="i in imglist" :key="i.fileBh"><img :src="i.imgUrl" alt=""></li><li class="puload-btn" id="upload" @click="chooseImgBtn()"><input type="file" id="choose" accept="image/*">+ </li></ul><div class="button-wriper" v-if="!vpersonalNotes.notesContext"><button class="login-btn" @click="submit">提交</button></div></div>
</template><script>
import $ from 'jquery'
import MHbar from '@/components/headerBar'
import { FormDataShim, getBlob} from '@/compress';export default {components: {MHbar},data () {return {dialogImageUrl: '',dialogVisible: false,picUrl: PIC_FILE_HOST,fileList: [],imglist: [],notesContext: '',canvas: null,ctx: null,tctx: null,tCanvas: null,vpersonalNotes: {},accessoryInfo: []}},methods: {chooseImgBtn() {var vm = thisvar filechooser = document.getElementById("choose");// 用于压缩图片的canvasvm.canvas = document.createElement("canvas");vm.ctx = vm.canvas.getContext('2d');// 瓦片canvasvm.tCanvas = document.createElement("canvas");vm.tctx = vm.tCanvas.getContext("2d");var maxsize = 1048576;filechooser.onchange = function() {if (!this.files.length) return;var files = Array.prototype.slice.call(this.files);if (vm.imglist.length > 9) {alert("最多同时只可上传9张图片");return;}files.forEach(function(file, i) {if (!/\/(?:jpeg|png|gif)/i.test(file.type)) returns;var reader = new FileReader();// 获取图片大小var size = file.size / 1024 > 1024 ? (~~(10 * file.size / 1024 / 1024)) / 10 + "MB" : ~~(file.size / 1024) + "KB";reader.onload = function() {var result = this.result;var img = new Image();img.src = result;//如果图片大小小于100kb,则直接上传if (result.length <= maxsize) {// vm.imglist.push(result)img = null;vm.upload(result, file.type);return;}// 图片加载完毕之后进行压缩,然后上传if (img.complete) {callback();} else {img.onload = callback;}function callback() {var data = vm.compress(img);vm.upload(data, file.type);img = null;}};reader.readAsDataURL(file);})}},// 使用canvas对大图片进行压缩compress(img) {const vm = thisvar initSize = img.src.length;var width = img.width;var height = img.height;//如果图片大于四百万像素,计算压缩比并将大小压至400万以下var ratio;if ((ratio = width * height / 4000000) > 1) {ratio = Math.sqrt(ratio);width /= ratio;height /= ratio;} else {ratio = 1;}vm.canvas.width = width;vm.canvas.height = height;// 铺底色vm.ctx.fillStyle = "#fff";vm.ctx.fillRect(0, 0, vm.canvas.width, vm.canvas.height);//如果图片像素大于100万则使用瓦片绘制var count;if ((count = width * height / 1000000) > 1) {count = ~~(Math.sqrt(count) + 1); //计算要分成多少块瓦片//  计算每块瓦片的宽和高var nw = ~~(width / count);var nh = ~~(height / count);vm.tCanvas.width = nw;vm.tCanvas.height = nh;for (var i = 0; i < count; i++) {for (var j = 0; j < count; j++) {vm.tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh);vm.ctx.drawImage(vm.tCanvas, i * nw, j * nh, nw, nh);}}} else {vm.ctx.drawImage(img, 0, 0, width, height);}//进行最小压缩var ndata = vm.canvas.toDataURL('image/jpeg', 0.1);console.log('压缩前:' + initSize);console.log('压缩后:' + ndata.length);console.log('压缩率:' + ~~(100 * (initSize - ndata.length) / initSize) + "%");vm.tCanvas.width = vm.tCanvas.height = vm.canvas.width = vm.canvas.height = 0;return ndata;},// 图片上传,将base64的图片转成二进制对象,塞进formdata上传upload(basestr, type) {const vm = thisvar text = window.atob(basestr.split(",")[1]);var buffer = new Uint8Array(text.length);var pecent = 0, loop = null;for (var i = 0; i < text.length; i++) {buffer[i] = text.charCodeAt(i);}var blob = getBlob([buffer], type);var xhr = new XMLHttpRequest();var formdata = this.getFormData();formdata.append('file', blob);xhr.open('post', this.picUrl);xhr.withCredentials = true;xhr.send(formdata);xhr.onreadystatechange = function() {if (xhr.readyState == 4 && xhr.status == 200) {var jsonData = JSON.parse(xhr.responseText);var imagedata = jsonData || {};var text = imagedata.resultCode === 0 ? '上传成功' : '上传失败';if(imagedata.resultCode === 0) {vm.imglist.push({fileBh: imagedata.record.fileBh,imgUrl: vm.picUrl + imagedata.record.fileBh})} else {vm.$toast.message('上传失败')}console.log(text + ':' + imagedata.record.fileBh);clearInterval(loop);console.log(vm.imglist)//当收到该消息时上传完毕if (imagedata.resultCode !== 0) return;}}},/*** 获取formdata*/getFormData() {var isNeedShim = ~navigator.userAgent.indexOf('Android')&& ~navigator.vendor.indexOf('Google')&& !~navigator.userAgent.indexOf('Chrome')&& navigator.userAgent.match(/AppleWebKit\/(\d+)/).pop() <= 534;return isNeedShim ? new FormDataShim() : new FormData()},getFileList(blob) {var formdata = this.getFormData()formdata.append('file', blob)this.$http.post(this.picUrl, formdata, { headers: {'Content-Type': 'multipart/form-data'} }).then((res) => {if(res.data.resultCode === 0) {this.imglist.push({fileBh: res.data.record.fileBh,imgUrl: this.picUrl + res.data.record.fileBh})} else {this.$toast.message(res.data.msg)}})},notesAccessory(bh) {var list = []this.imglist.forEach(i => {list.push(i.fileBh)});var data = {notesBh: bh,fileBh: list}this.$http.post('/api/v1/notesAccessory', data).then((res) => {if(res.data.resultCode === 0) {this.$router.go(-1)}})},submit() {var data = {notesDTO: {notesContext: this.notesContext,attendeesBh: this.$route.params.id,notesName: ''}}if(!this.notesContext) {this.$toast.message('笔记内容不能为空')return false}if(!this.imglist.length) {this.$toast.message('笔记照片不能为空')return false}this.$http.post('/api/v1/notes', data).then((res) => {this.notesAccessory(res.data.record)})},getdeetail() {if(this.$route.params.notesBh !== 'add') {this.$http.get('/api/v1/notes/' + this.$route.params.notesBh).then((res) => {this.vpersonalNotes = res.data.record.vpersonalNotesthis.accessoryInfo = res.data.record.accessoryInfo})}}},mounted() {this.getdeetail()}
}
</script><style lang="scss" scoped>
.me-detail {font-size: 28px;.detail-title {padding-top: 46px;margin-bottom: 10px;margin-left: 46px;font-weight: 600;font-size: 28px;position: relative;&::before {content: '';display: inline-block;width: 8px;height: 27px;background: #000;position: absolute;left: -16px;bottom: 3px;}}.note-textarea, p {text-align: justify;padding: 25px 30px;line-height: 36px;margin-bottom: 20px;color: #777;width: 100%;min-height: 260px;}.note-textarea {box-shadow: 0 0 0 0.013333rem #fa4b31 inset;margin: 0 auto;width: 92%;display: block;}p {border-bottom: 1px solid #dedede;}.button-wriper {width: 100%;text-align: center;margin-top: 50px;margin-bottom: 30px;bottom: 120px;.login-btn {display: block;width: 520px;height: 78px;color: #fff;margin: 67px auto 0 auto;border-radius: 41.2px;background: #fa4b31;letter-spacing: 20px;}}
}
li{list-style-type: none;}a,input{outline: none;-webkit-tap-highlight-color:rgba(0,0,0,0);}#choose{opacity: 0;width: 100%;height: 100%;overflow: hidden;z-index: 1000;position: absolute;left: 0;}canvas{width: 100%;border: 1px solid #000000;}// #upload{display: block;margin: 10px;height: 60px;text-align: center;line-height: 60px;border: 1px solid;border-radius: 5px;cursor: pointer;}.touch{background-color: #ddd;}.img-list{margin: 10px 5px;li {display: inline-block;}.img-list-li {width: 200px;height: 200px; background-size: 100% 100%; display: inline-block;position: relative;display: inline-block;margin: 30px 0px 20px 30px;background: #fff no-repeat center;background-size: cover;img {width: 200px;height: 200px;margin-top: -20px; }}}.puload-btn {text-align: center;line-height: 200px;width: 200px;height: 200px; border: 1px solid #fa4b31;margin-left: 30px;font-size: 50px;color: #fa4b31;position: relative;}
</style>

compress.js

/*** 获取blob对象的兼容性写法* @param buffer* @param format* @returns {*}*/
const getBlob = function (buffer, format) {try {return new Blob(buffer, {type: format})} catch (e) {var bb = new (window.BlobBuilder || window.WebKitBlobBuilder || window.MSBlobBuilder)buffer.forEach(function(buf) {bb.append(buf)})return bb.getBlob(format)}
}/*** formdata 补丁, 给不支持formdata上传blob的android机打补丁* @constructor*/
const FormDataShim = function () {console.warn('using formdata shim')var o = this,parts = [],boundary = Array(21).join('-') + (+new Date() * (1e16 * Math.random())).toString(36),oldSend = XMLHttpRequest.prototype.sendthis.append = function (name, value, filename) {parts.push('--' + boundary + '\r\nContent-Disposition: form-data; name="' + name + '"')if (value instanceof Blob) {parts.push('; filename="' + (filename || 'blob') + '"\r\nContent-Type: ' + value.type + '\r\n\r\n')parts.push(value)} else {parts.push('\r\n\r\n' + value)}parts.push('\r\n')}// Override XHR send()XMLHttpRequest.prototype.send = function (val) {var fr,data,oXHR = thisif (val === o) {// Append the final boundary stringparts.push('--' + boundary + '--\r\n')// Create the blobdata = getBlob(parts)// Set up and read the blob into an array to be sentfr = new FileReader()fr.onload = function () {oldSend.call(oXHR, fr.result)}fr.onerror = function (err) {throw err}fr.readAsArrayBuffer(data)// Set the multipart content type and boudarythis.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary)XMLHttpRequest.prototype.send = oldSend} else {oldSend.call(this, val)}}
}export { FormDataShim, getBlob }

移动端vue调用照相机及相册相关推荐

  1. vue调用手机相机相册_移动端vue调用照相机及相册

    个人总结 {{vpersonalNotes.notesContext}} 图片 + 提交 compress.js /** * 获取blob对象的兼容性写法 * @param buffer * @par ...

  2. vue调用手机相机相册_详解Vue调用手机相机和相册以及上传

    组件 选中{{imgList.length}}张文件,共{{bytesToSize(this.size)}} javaScript代码 export default { name: "cam ...

  3. 调用照相机和相册功能

    IOS成长之路-调用照相机和相册功能 分类: IOS2013-01-04 17:05 12786人阅读 评论(0) 收藏 举报 打开相机: [cpp] view plaincopy //先设定sour ...

  4. vue移动端调用照相机及相册

    <template><div class="me-detail"><m-hbar title="个人笔记"/><div ...

  5. Vue调用手机相机和相册以及上传

    组件 <template><div><input id="upload_file" type="file" style=" ...

  6. IOS成长之路-调用照相机和相册功能

    打开相机: //先设定sourceType为相机,然后判断相机是否可用(ipod)没相机,不可用将sourceType设定为相片库UIImagePickerControllerSourceType s ...

  7. Vue 移动端调用相机和相册实现图片上传

    一.基础知识: 1.只调用手机相册 <input type="file" accept="image/*;" > 2.只调用手机相机拍照 <i ...

  8. vue调用电脑端摄像头实时拍照

    vue调用电脑端摄像头实时拍照 需求描述 功能实现 效果展示 需求描述 点击照相机拍照,弹出照相机拍照弹窗,点击拍照按钮,截取录像的帧,点击保存,提交数据给后台. 功能实现 1.html模块 //点击 ...

  9. h5 调起相机_H5移动端调用相机或相册

    一: 前提 在做H5时,有时要实现拍照功能,这就要调取手机端的相机,当时,在网上搜了很多能实现的方式,最后还是用html5自带的 input标签,实现移动端调用手机摄像头.好了,话不多说,下面就是我实 ...

最新文章

  1. 「九章」量子计算优越性遭北大院士质疑,潘建伟陆朝阳长文回应
  2. Java: 复制文件最快、高效率的方法
  3. 信用风险模型(申请评分、行为评分)与数据准备(违约期限、WOE转化)
  4. explain都不懂,还好意思说会SQL调优?
  5. php js 验证码,js实现验证码的方法
  6. vue 里面引入高德地图
  7. ASP.NET弹出对话框并跳转页面
  8. 基于JAVA+SpringMVC+MYSQL的网上选课系统
  9. php+ajax+js注册源码,将Ajax封装至js文件中(用户注册源码实例)
  10. P2044 [NOI2012]随机数生成器
  11. Android 面试题(答案最全) 转:http://www.jobui.com/mianshiti/it/android/2682/
  12. 凑硬币算法C语言,《凑硬币》 动态规划算法入门
  13. 初中OJ1998【2015.8.3普及组模拟赛】饥饿的WZK(hunger)
  14. 人工智能学习路线图(超详细、超全面)
  15. 9_1 法律法规标准化
  16. Linux 搭建 discuz 论坛
  17. 通常我们将python语言程序保存在一个后缀_知到毛概章节测试答案2020
  18. Elasticsearch深入理解(十二)——SocketTimeoutException解决方案
  19. 空格键删字符解决办法
  20. vmlite-android 屏幕旋转90,How to change the screen size of vmlite android?

热门文章

  1. 联想z5 android pie,联想z5成功吃上安卓pie
  2. UVa 10306. e-Coins
  3. 水浒歪传--郭德纲相声
  4. byval 和byref的区别,今天刚明白。
  5. 猪八戒java开发,猪八戒--Java开发
  6. 话费对接充值平台_手机话费误充给他人怎么办?小编带你找运营商要回来
  7. 现在的我,不想做管理
  8. 【POJ No. 3764】 最长xor 路径 The xor-longest Path
  9. 驱动——LED灯循环闪烁
  10. OpenCV - SIFT-SURF(Python实现)