组件示例图

组件代码 upload_img.vue

  <div id="uploadImg">
<div class="upload_image_box" v-show="show1">
<div class="upload_image">
<div class="photo_box" @click="actionSheet()">
<img class="icon_photo" src="../../assets/images/icon_photo.png" />
<p><span>{{$t('m.btn_0011')}}</span></p>
</div>
</div>
</div>
<div class="uploaded" v-show="show2">
<div v-for="(item,index) in imgLists" class="imgItem">
<img @click="deleteImg(index)" class="delete" src="../../assets/images/icon_x.png">
<img :src="item" class="img" @click="previewPicture(index)">
</div>
<div class="imgUpload" @click="actionSheet()">
<img class="icon_photo" src="../../assets/images/icon_photo.png" />
<p><span>{{$t('m.btn_0011')}}</span></p>
</div>
</div>
</div>
</template> <script>
import {Toast, Indicator} from "mint-ui"
export default({
props: [
'imgList',
'showUpload',
'showUploaded',
'maxPic',//用户传的最大的照片数目
'zipTo' // 压缩到多少KB(可选,默认到1024K)
],
data() {
return {
show1: true,
show2: false
}
},
computed: {
imgLists() {
return this.imgList || []
},
getMaxPic() {
return this.maxPic*1 || 1
}
},
watch: {
imgLists(newValue, oldValue) {
if(newValue.length > 0){
this.show1 = false;
this.show2 = true;
} else {
this.show1 = true;
this.show2 = false;
}
}
},
methods: {
actionSheet() {
let that = this
plus.nativeUI.actionSheet({
title: "获取照片",
cancel: "取消",
buttons: [
{
title: "拍照"
},
{
title: "相册"
},
]
},
function(e) { //点击回调
switch(e.index) {
case 0:
break;
case 1:
that.cameraImg(); /*拍照*/
break;
case 2:
that.galleryImg(); /*打开相册*/
break;
default:
break;
}
}
);
},
galleryImg() {
let that = this;
plus.gallery.pick(
function(e) {
for (var i in e.files) {
var path = e.files[i]; // file:///storage/emulated/0/截屏、超级截屏_20180803_112739.png
if (that.imgLists.length < that.getMaxPic) {
plus.io.resolveLocalFileSystemURL(path, function(entry) { //entry 请求到的目录或文件对象
var fileSystem = entry.fileSystem
var fileInfo = {};
entry.file(function(file){ // 获取文件信息
fileInfo = file;
let zipTo = that.zipTo; // KB
that.zipPicture(path, fileInfo, zipTo)
.then(function(zipObj){
if(zipObj && zipObj.target){
Indicator.open();
console.log('107:', that.imgLists, zipObj.target,!that.imgLists.includes(zipObj.target))
if(!that.imgLists.includes(zipObj.target)){
that.getBase64(zipObj.target) //zipObj.target -压缩后的文件所在的路径
.then(function(dataURL){ //dataUrl -压缩后的文件的base64编码
that.dataURLtoFile(dataURL, fileInfo.name)
.then(function(f){ // f - base64转成文件后的文件对象
let fileBigObj = {
path: zipObj.target,
file: f
}
console.log(fileBigObj);
that.$emit('pickPic',fileBigObj)
return fileBigObj;
})
})
}else{
Toast({message: '同一张图片不能重复提交'})
}
}
})
.catch(function(zipErr){
that.zipErrHandle(zipErr, fileInfo)
})
})
})
} else {
that.$alert(i18n.t('m.msg_0005')+`${that.getMaxPic}`+i18n.t('m.msg_0007'));
break;
}
}
},
function(error) {
Indicator.close();
if(error.code == 12){
Toast({message: '用户取消'})
}else{
that.galleryPermission(error)
}
},
{
filter: "image",
multiple: true, // 设置了此项,选择成功返回的是一个包含键名为files的路径数组的对象,否则为单一路径;
maximum: that.getMaxPic - that.imgLists.length
});
},
cameraImg() { // 调用相机
let that = this;
let c = plus.camera.getCamera();
let hasCamera = that.cameraPermission()// 相机权限
if(!hasCamera) return
c.captureImage(function(e) {
//获取操作文件或目录对象
plus.io.resolveLocalFileSystemURL(e, function(entry) { //entry 请求到的目录或文件对象
that.showUpload = false;
that.showUploaded = true;
var path = entry.toLocalURL() //toLocalURL: 获取目录路径转换为本地路径URL地址
//压缩图片
plus.io.resolveLocalFileSystemURL(path, function(entry) { //entry 请求到的目录或文件对象
var fileSystem = entry.fileSystem
var fileInfo = {};
entry.file(function(file){ // 获取文件信息
fileInfo = file;
let zipTo = that.zipTo; // KB
that.zipPicture(path, fileInfo, zipTo)
.then(function(zipObj){
if(zipObj && zipObj.target){
Indicator.open();
if(!that.imgLists.includes(zipObj.target)){
that.getBase64(zipObj.target) //zipObj.target -压缩后的文件所在的路径
.then(function(dataURL){ //dataUrl -压缩后的文件的base64编码
that.dataURLtoFile(dataURL, fileInfo.name)
.then(function(f){ // f - base64转成文件后的文件对象
let fileBigObj = {
path: zipObj.target,
file: f
}
console.log(fileBigObj);
that.$emit('pickPic',fileBigObj)
return fileBigObj;
})
})
} else {
Toast({message: '同一张图片不能重复提交'})
}
}
})
.catch(function(zipErr){
that.zipErrHandle(zipErr, fileInfo)
})
})
}) }, function(e) {
console.log("读取拍照文件错误:" + e.message);
});
}, function(error) {
if(error.code == 11){
Toast({message: '用户取消'})
}
}, {
filename: "_doc/" //拍照文件存放的路径
})
},
deleteImg(index) {
let deletePic = this.imgLists[index]
this.$emit('deletePic', deletePic)
},
/**
* @description 打开相册失败,请求系统权限
* @param {Error} e
*/
galleryPermission(e) {
var galleryPermission = plus.navigator.checkPermission("GALLERY");
if (plus.os.name == "iOS") {
if (e.code == 8) {
plus.nativeUI.alert("您的相册权限未打开,请在当前应用设置-隐私-相册来开打次权限", function(event){
plus.runtime.openURL('prefs:root=Privacy');
})
}
} else if (plus.os.name == "Android") {
if (e.code != 12) {
plus.nativeUI.alert("您的相册权限未打开,请在应用列表中将您的权限打开", function() {
// var android = plus.android.importClass('com.android.settings');
var main = plus.android.runtimeMainActivity();
var Intent = plus.android.importClass("android.content.Intent");
var mIntent = new Intent('android.settings.APPLICATION_SETTINGS');
main.startActivity(mIntent);
});
}
}
},
cameraPermission() {
var cameraPermission = plus.navigator.checkPermission("CAMERA");
if( cameraPermission == "denied" ){// 阻塞
if (plus.os.name == "iOS") {
plus.nativeUI.alert("您的相机权限没有打开,请在当前应用设置-隐私-相机来开打次权限", function(event){
plus.runtime.openURL('prefs:root=Privacy');
})
} else if (plus.os.name == "Android") {
plus.nativeUI.alert("您的相机权限没有打开,请在应用列表中将权限打开", function() {
// var android = plus.android.importClass('com.android.settings');
var main = plus.android.runtimeMainActivity();
var Intent = plus.android.importClass("android.content.Intent");
var mIntent = new Intent('android.settings.APPLICATION_SETTINGS');
main.startActivity(mIntent);
});
}
return false
}else{
return true
}
},
// zipPicture(pth, cb) {
// return new Promise(function(resolve, reject){
// let conf = {
// src: pth,
// dst:pth,
// overwrite:true,
// quality: 50
// };
// plus.zip.compressImage(conf, function(data) {
// resolve(data)
// }, function(err) {
// Toast({message:'图片压缩失败,错误编码:'+err.code})
// reject(err);
// });
// })
// },
previewPicture(index) {
plus.nativeUI.previewImage(this.imgLists,{current:index});
},
zipPicture(pth, fileInfo, zipTo) {
return new Promise(function(resolve, reject){
let zipName = fileInfo.name,
quality = 0.50;
typeof zipTo === 'number' ? zipTo>0 ? zipTo = zipTo :zipTo = 1024 : zipTo = 1024; //默认压缩到1M
zipTo < fileInfo.size ? quality = zipTo / fileInfo.size : quality = 1;
let conf = {
src: pth,
dst: '_doc/'+zipName,//pth, // 转换目标图片的路径
overwrite:false, //true, // 是否覆盖
quality: quality * 100 // 取值(0,100]
};
plus.zip.compressImage(conf, function(data) {
resolve(data)
}, function(err) {
// plus.nativeUI.alert('图片压缩失败,错误编码:'+err.code)
reject(err);
});
})
},
dataURLtoFile(dataurl, filename) {//将base64转换为文件
//atob()- window内置的函数;ASCII码转binary ;不支持非ASCII码转换,
//btoa()- window内置函数;binary转ASCII;不支持非ASCII码转换,
return new Promise(function(resolve, reject){
var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n);
}
var file = new File([u8arr], filename, {type:mime})
resolve(file);
})
},
getBase64(url){
return new Promise(function(resolve, reject){
var canvas = document.createElement('canvas'),//创建canvas元素
dataURL= '',
ctx = canvas.getContext('2d'),
img = new Image; //通过构造函数来创建的 img 实例,在赋予 src 值后就会立刻下载图片,相比 createElement() 创建 <img> 省去了 append(),也就避免了文档冗余和污染
img.crossOrigin = 'Anonymous';
img.onload = function(){
canvas.height = img.height;
canvas.width = img.width;
ctx.drawImage(img,0,0,);
dataURL = canvas.toDataURL('image/jpeg', 1);
resolve(dataURL)
// callback?callback(dataURL):null; //调用回调函数
canvas = null;
};
img.src = url; // 图片预览
})
},
zipErrHandle(zipErr, fileInfo) { // 压缩失败
let that = this;
if(zipErr.code == -5){ // 错误编码为-5--该路径已经存在该文件;跳过压缩,直接获取原来存在的文件
var zipRelatePath = "_doc/"+ fileInfo.name;
plus.io.resolveLocalFileSystemURL( zipRelatePath, function(entry){
var zipLocalURL = entry.toLocalURL()
console.log('336:', that.imgLists, zipLocalURL, !that.imgLists.includes(zipLocalURL))
if( !that.imgLists.includes(zipLocalURL)){
that.getBase64(zipLocalURL) //zipLocalURL -压缩后的文件所在的'绝对路径'
.then(function(dataURL){ //dataUrl -压缩后的文件的base64编码
that.dataURLtoFile(dataURL, fileInfo.name)
.then(function(f){ // f - base64转成文件后的文件对象
let fileBigObj = {
path: zipLocalURL,
file: f
}
console.log(fileBigObj);
that.$emit('pickPic',fileBigObj)
return f;
})
})
} else {
Toast({message: '同一张图片不能重复提交'})
}
}, function(){ })
}
}
}
})
</script> <style lang="less" scoped="scoped">
#uploadImg{
.upload_image_box{padding: 34px;width: 100%;box-sizing: border-box;background: #fff;
.upload_image{background: #f2f2f2;width: 100%;border: 1px dashed #e6e6e6;/*no*/border-radius: 10px;padding: 110px 0;
.photo_box{width: 100%;
.icon_photo{width: 44px;height: 40px;position: relative;left: 50%;margin-left: -22px;}
p{font-size: 24px;/* px */color: #999999;text-align: center;margin: 0;}
}
}
}
.uploaded{padding: 34px;width: 100%;box-sizing: border-box;background: #fff;
.imgItem{width: 214px;height: 214px;display: inline-block;border: 2px dashed #e5e5e5;border-radius: 20px;position: relative;vertical-align: top;margin-right: 20px;
.delete{width: 30px;height: 30px;position: absolute;right: 0;}
.img{width: 100%;height: 100%;border-radius: 20px;}
}
.imgUpload{width: 214px;height: 214px;display: inline-block;background: #f2f2f2;padding: 66px 0;box-sizing: border-box;border: 2px dashed #e5e5e5;border-radius: 20px;
.icon_photo{width: 44px;height: 40px;position: relative;left: 50%;margin-left: -22px;}
p{font-size: 24px;/* px */color: #999999;text-align: center;margin: 0;}
}
}
}
</style>

父组件使用代码

<template>
<upload_img :imgList='imgList' :maxPic='"6"' @pickPic='pickPic($event)' @deletePic='deletePic' :zipTo = 'zipTo'></upload_img>
</template> <script>
import upload_img from '../../../common/upload_img' export default ({
data() {
return {
imgList: [],
zipTo: 1024 // KB
}
},
components: {
upload_img
},
methods: {
pickPic(rest){ /*选择照片成功后回调函数*/
setTimeout(function(){
Indicator.close();
},200)
let that = this;
let fickedFile = rest.file; // 选中的文件对象
rest && that.imgList.push(rest.path)
console.log(rest);
//... 上传图片逻辑
},
deletePic(rest) {
let that = this;
let index = that.imgList.indexOf(rest);
that.imgList.splice(rest, 1)
}
}
})
</script>

移动端Vue图片获取,压缩,预览组件-upload-img(H5+获取照片,压缩,预览)的更多相关文章

  1. 从0开始做一个的Vue图片/ 文件选择(上传)组件[基础向]

    原文:http://blog.csdn.net/sinat_17775997/article/details/58585142 之前用Vue做了一个基础的组件 vue-img-inputer ,下面就 ...

  2. vue图片上传的简单组件

    <template> <div class="rili" id="rili"> <div class="updel&qu ...

  3. [javascript]——移动端 HTML5 图片上传预览和压缩

    在开发移动端web网页中,我们不可避免的会遇到文件上传的功能,但由于手机图片尺寸太大,上传时间过长导致用户体验太差,就需要在上传前对图片进行一定的压缩. 在代码之前,有必要先了解我们即将使用到的几个A ...

  4. vue图片点击放大预览

    第一种:viewerjs使用介绍(PC.移动端都兼容) 1.先安装依赖 npm install v-viewer --save 2.main.js内引用并注册调用 //main.js import V ...

  5. vue封装原生的可预览裁剪上传图片插件H5,PC端都可以使用

    思路:1.先做出一个上传的图片的上传区 <!-- 上传区 --> <label for="fileUp"> <div class="upBo ...

  6. 土旦:移动端 Vue+Vant 的Uploader 实现 :上传、压缩、旋转图片

    面向百度开发 html <van-uploader :after-read="onRead" accept="image/*"> <img s ...

  7. js/vue图片压缩

    js版 新建compressImage.js,内容如下: // 将base64转换为blob(有需要可加上,没需要可不加) function convertBase64UrlToBlob(urlDat ...

  8. 图片预览组件PhotoView

    图片预览组件PhotoView PhotoView是一款图片预览组件,广泛应用于大图的查看.该组件支持图片手势缩放.旋转等功能.它可以很好的和ViewPager.Picasso等组件结合,实现各种复杂 ...

  9. 在ASP.NET MVC下实现单个图片上传, 客户端服务端双重限制图片大小和格式, 服务端裁剪图片

    在"MVC文件图片ajax上传轻量级解决方案,使用客户端JSAjaxFileUploader插件01-单文件上传"一文中,使用JSAjaxFileUploader这款插件实现了单文 ...

随机推荐

  1. pat 1035 Password(20 分)

    1035 Password(20 分) To prepare for PAT, the judge sometimes has to generate random passwords for the ...

  2. hdu 1028 Sample Ignatius and the Princess III (母函数)

    Ignatius and the Princess III Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K ...

  3. 从最近面试聊聊我所感受的.net天花板

    #0 前言 入职新公司没多久,闲来无事在博客园闲逛,看到园友分享的面试经历,正好自己这段时间面试找工作,也挺多感想的,干脆趁这个机会总结整理一下.博主13年开始实习,14年毕业.到现在也工作五六年了. ...

  4. B0宏

    在编译android平台用的ffmpeg时,抛出这样一个错误: 这句代码怎么看都找出有毛病,为什么B0会报错? 翻看aaccoder.c,也没有发现问题.为什么B0就成了一个常量数字,这里只有一个可能 ...

  5. python:Asyncio模块处理“事件循环”中的异步进程和并发执行任务

    python模块Asynico提供了管理事件.携程.任务和线程的功能已经编写并发代码的同步原语. 组成模块: 事件循,Asyncio 每个进程都有一个事件循环. 协程,子例程概念的泛化,可以暂停任务, ...

  6. vue 安装指令

    vue init webpack 项目名 创建项目cd 项目名 打开项目 npm install vuex --save 安装vuex在一个模块化的打包系统中,您必须显式地通过 Vue.use() 来 ...

  7. (六)OpenStack---M版---双节点搭建---Neutron安装和配置

    ↓↓↓↓↓↓↓↓视频已上线B站↓↓↓↓↓↓↓↓ >>>>>>传送门 1.创建网络服务数据库 2.获得 admin 凭证来获取只有管理员能执行的命令的访问权限 3.创 ...

  8. 小白学习python第一天,Pycharm破解与用法(持续更新)

    目录 Pycharm安装与破解及汉化 Pycharm安装 Pycharm破解 Pycharm汉化 Pycharm使用 添加作者.时间等信息 补充 @ Pycharm安装与破解及汉化 本人最近开始找到了 ...

  9. Selenium+Java(二)Selenium打开IE浏览器

    前言 已在Eclipse中配置完成Selenium的相关配置,不知道如何配置的可参考我的另一篇博文:https://www.cnblogs.com/yogouo/p/11946940.html 打开I ...

  10. Stack Overflow 上 370万浏览量的一个问题:如何比较 Java 的字符串?

    在逛 Stack Overflow 的时候,发现了一些访问量像喜马拉雅山一样高的问题,比如说这个:如何比较 Java 的字符串?访问量足足有 370万+,这不得了啊!说明有很多很多的程序员被这个问题困 ...