小程序 多图片上传到服务端(图片压缩)
主要是利 <canvas /> 标签(原因为了压缩图片), 再利用 base64转码 , 写入数组, 发送到服务端(这里有个坑,小程序 发送的数组如 [ "13","24" ] 服务端接收的时候为 [ "13,24" ] ,解决方案就是在(接口)服务端 用切割把它们分出来 )。
本文主要写 : 我,把多个图片压缩 ,再转base64编码,把编码写进数组(个人案例)。
效果图
直上代码 复制即可
.wxml
<!-- 实名注册 -->
<view id="privacy" class="mui-page nomeno">
<view style="height: 100%;display: block;overflow: auto;">
<view> </view>
<view class="mui-page-content" style="overflow: auto;">
<view id="xxx" style="overflow: auto;">
<view>
<view class="bodyboxshiy">
<view class="gongzhangxinxitianxie">
<!--工长信息填写-->
<view class="dixbox">
<view class="neirongtongy">
<view class="topboxview" style='display: inline-block;'>
<label style="color: red;">*</label>真实姓名
</view>
<view class="butnboxdiv">
<input bindinput='bind_xm' type="text" style='margin-left: 6%;'></input>
</view>
</view>
</view>
<view class="dixbox">
<view class="neirongtongy">
<view class="topboxview" style='display: inline-block;'>
<label style="color: red;">*</label>身份证号
</view>
<view class="butnboxdiv">
<input bindinput='bind_sfz' type="text" maxlength="20" style='margin-left: 6%;'></input>
</view>
</view>
</view>
<view style="padding: 0 20px;">
<view class="l_title">
<view class="l_title_td" style="">
</view>
<view class="l_title_td_n" style="color: #749dff;">
身份认证照片
</view>
<view class="l_title_td">
</view>
</view>
</view>
<view>
<view class="imgboxsy " id="1">
<view class="shenfenzbyn " style="height: 100%;width: auto;" bindtap="chooseImg" data-index="0">
<image src="{{tupianurl1}}" class="" style='width:300px; height:210px;'></image>
<!-- canvas 标签定位有问题(自定义的定位改变不了) 在手机上会出现绝对定位 隐藏canvas 就不能绘制图片 <view style="position:fixed;top:999999999999999999999rpx;"> 就能解决这问题 -->
<view style="position:fixed;top:999999999999999999999rpx;">
<canvas style='left: 10000rpx' id='scannerCanvas' canvas-id='scannerCanvas' disable-scroll="true" style="height:{{height}}px;width:{{width}}px;" />
</view>
</view>
</view>
<view class="imgboxsy " id="2">
<view class="shenfenzbyn " style="height: 100%;width: auto;auto;"bindtap="chooseImg" data-index="1">
<image src="{{tupianurl2}}" style='width:300px; height:210px;'></image>
</view>
</view>
<view class="imgboxsy " id="3">
<view class="shenfenzbyn " style="height: 100%;width: auto;auto;"bindtap="chooseImg" data-index="2">
<image src="{{tupianurl3}}" style='width:300px; height:210px;'></image>
</view>
</view>
<view class="imgboxsy " id="4">
<view class="shenfenzbyn " style="height: 100%;width: auto;auto;"bindtap="chooseImg" data-index="3">
<image src="{{tupianurl4}}" style='width:300px; height:210px;'></image>
</view>
</view>
</view>
<view style="width: 95%;padding-left:4%;">
<label class="fr font checked-lable" style='width:24px;height:24px' catchtap='checkedTap'>
<radio checked="{{checked}}" />
</label>
<label style="line-height: 38px;font-size:10px;color: #ADADAD;padding-right: 0px;height: 39px;overflow: hidden;">我已阅读并同意遵守
</label>
<label style="line-height: 38px;font-size:12px;color: #2DB7FC;padding-right: 0px;height: 39px;overflow: hidden;" bindtap='bind_xy'>《xxxxx服务协议》</label>
</view>
<view class="" id="bainjibtn" style="margin-bottom:30px;display: block; ;">
<view class="righttianxiebox" style="background-color: #ffdf05;" onclick="window.kos.reg_refers()" bindtap='bind_zhuce'>
<p>确认注册</p>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 实名注册 -->
.js
const app = getApp();
const upng = require('UPNG.js');//需要引用的js(UPNG.js pako.js)好像是UPNG.js内部引用pako.js 所有只需写一个
var PhysicalPhoto = ['', '', '', '']; //装4张图片bese64数组 (PhysicalPhoto数组写入 Page的data 里会报文件内容超出xxxx范围 于是我就写在外面了 而且Page的data数组操作太复责 var ss=[] 操作和以前差不多 )
Page({
/**
* 页面的初始数据
*/
data: {
checked: false,//单选框的
TrueName: "",//姓名
IdCardCode: "",//身份证
width: 300,//压缩图片的宽
height: 210,//压缩图片的高
//(默认图片)图片自己可改
tupianurl1: '/image/reg/reg4.png', //显示的图片路径 在页面写 有问题 页面的默认将 /image/reg/reg4.png
tupianurl2: '/image/reg/reg5.png',// 转为 htmls://xxxxx 网络路径 当页面写的是相对路径 时它会默认转
tupianurl3: '/image/reg/reg1.png',// 如果判断改 src 路径为htmls://xxxxx 会有其中一方加载不出
tupianurl4: '/image/reg/reg3.png',
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
}
//姓名输入改变
, bind_xm: function (e) {
var that = this;
that.setData({
TrueName: e.detail.value
})
}
//身份证输入改变
, bind_sfz: function (e) {
var that = this;
that.setData({
IdCardCode: e.detail.value
})
}
//注册账户
, bind_zhuce: function () {
}
//单选框
, checkedTap: function () {
var checked = this.data.checked;
this.setData({
"checked": !checked
})
}
// 选择照片1 用判断
, chooseImg: function (e) {
wx.chooseImage({
count: 1,
sizeType: ['compressed'],// 可以指定是原图还是压缩图,默认二者都有 'original',
sourceType: ['album', 'camera'],// 可以指定来源是相册还是相机,默认二者都有
success: (res) => {
var tempFilePaths = res.tempFilePaths[0];//
var canvas = wx.createCanvasContext('scannerCanvas')//id
// 1. 绘制图片至canvas
canvas.drawImage(tempFilePaths, 0, 0, this.data.width, this.data.height)
// 绘制完成后执行回调,API 1.7.0
canvas.draw(false, () => {
var that = this;
// 2. 获取图像数据, API 1.9.0
wx.canvasGetImageData({
canvasId: 'scannerCanvas',
x: 0,
y: 0,
width: this.data.width,
height: this.data.height,
success: (res) => {
let platform = wx.getSystemInfoSync().platform
if (platform == 'ios') {
// 兼容处理:ios获取的图片上下颠倒
res = this.reverseImgData(res)
}
// 3. png编码
let pngData = upng.encode([res.data.buffer], this.data.width, this.data.height)
// 4. base64编码 //let base64 = wx.arrayBufferToBase64(pngData)
// ;
PhysicalPhoto[e.currentTarget.dataset.index] = 'data:image/jpg;base64,' + wx.arrayBufferToBase64(pngData);
if (e.currentTarget.dataset.index == 0) {
that.setData({
tupianurl1: tempFilePaths
})
}
if (e.currentTarget.dataset.index == 0) {
that.setData({
tupianurl1: tempFilePaths
})
} else if (e.currentTarget.dataset.index == 1) {
that.setData({
tupianurl2: tempFilePaths
})
} else if (e.currentTarget.dataset.index == 2) {
that.setData({
tupianurl3: tempFilePaths
})
} else if (e.currentTarget.dataset.index == 3) {
that.setData({
tupianurl4: tempFilePaths
})
} else if (e.currentTarget.dataset.index == 4) {
that.setData({
tupianurl5: tempFilePaths
})
}
console.log('base64图片数组', PhysicalPhoto);
}
})
})
}
})
},
// 图片颠倒
reverseImgData(res) {
var w = res.width
var h = res.height
let con = 0
for (var i = 0; i < h / 2; i++) {
for (var j = 0; j < w * 4; j++) {
con = res.data[i * w * 4 + j]
res.data[i * w * 4 + j] = res.data[(h - i - 1) * w * 4 + j]
res.data[(h - i - 1) * w * 4 + j] = con
}
}
return res
}
})
.wxss (里面有很多没用的类)
.mui-views,
.mui-view,
.mui-pages,
.mui-page,
.mui-page-content {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
width: 100%;
height: 100%;
background-color: #FFFBFC;
}
.mui-pages {
top: 46px;
height: auto;
}
.mui-scroll-wrapper,
.mui-scroll {
background-color: #FFFBFC;
}
.mui-page.mui-transitioning {
-webkit-transition: -webkit-transform 300ms ease;
transition: transform 300ms ease;
}
.mui-page-left {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
.mui-ios .mui-page-left {
-webkit-transform: translate3d(-20%, 0, 0);
transform: translate3d(-20%, 0, 0);
}
.mui-navbar {
position: fixed;
right: 0;
left: 0;
z-index: 10;
height: 44px;
background-color: #f7f7f8;
}
.mui-navbar .mui-bar {
position: absolute;
background: transparent;
text-align: center;
}
.mui-android .mui-navbar-inner.mui-navbar-left {
opacity: 0;
}
.mui-ios .mui-navbar-left .mui-left,
.mui-ios .mui-navbar-left .mui-center,
.mui-ios .mui-navbar-left .mui-right {
opacity: 0;
}
.mui-navbar .mui-btn-nav {
-webkit-transition: none;
transition: none;
-webkit-transition-duration: .0s;
transition-duration: .0s;
}
.mui-navbar .mui-bar .mui-title {
display: inline-block;
width: auto;
}
.mui-page-shadow {
position: absolute;
right: 100%;
top: 0;
width: 16px;
height: 100%;
z-index: -1;
content: '';
}
.mui-page-shadow {
background: -webkit-linear-gradient(left, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 10%, rgba(0, 0, 0, .01) 50%, rgba(0, 0, 0, .2) 100%);
background: linear-gradient(to right, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 10%, rgba(0, 0, 0, .01) 50%, rgba(0, 0, 0, .2) 100%);
}
.mui-navbar-inner.mui-transitioning,
.mui-navbar-inner .mui-transitioning {
-webkit-transition: opacity 300ms ease, -webkit-transform 300ms ease;
transition: opacity 300ms ease, transform 300ms ease;
}
.mui-page {
display: none;
}
.mui-pages .mui-page {
display: block;
}
.mui-page .mui-table-view:first-child {
margin-top: 15px;
}
.mui-page .mui-table-view:last-child {
margin-bottom: 30px;
}
.mui-table-view {
margin-top: 20px;
}
.mui-table-view span.mui-pull-right {
color: #999;
}
.mui-table-view-divider {
background-color: #efeff4;
font-size: 14px;
}
.mui-table-view-divider:before,
.mui-table-view-divider:after {
height: 0;
}
.head {
height: 40px;
}
#head {
line-height: 40px;
}
.head-img {
width: 40px;
height: 40px;
}
#head-img1 {
position: absolute;
bottom: 10px;
right: 40px;
width: 40px;
height: 40px;
}
.update {
font-style: normal;
color: #999999;
margin-right: -25px;
font-size: 15px
}
.mui-fullscreen {
position: fixed;
z-index: 20;
background-color: #000;
}
.mui-ios .mui-navbar .mui-bar .mui-title {
position: static;
}
/*问题反馈在setting页面单独的css*/
#feedback .mui-popover{
position: fixed;
}
#feedback .mui-table-view:last-child {
margin-bottom: 0px;
}
#feedback .mui-table-view:first-child {
margin-top: 0px;
}
.mui-plus.mui-plus-stream .mui-stream-hidden{
display: none !important;
}
.l_tra{
width: 100%;
height: 44px;
border: 1px solid #dddddd;
border-radius: 5px;
background-color: #fff;
margin-top: 20px;
}
.l_tra .l_cm_30{
width: 33%;
float: left;
text-align: center;
}
.l_tra .l_cm_30 .l_cm_30_t{
font-size: 13px;
color: #808080;
margin-top: 5px;
font-weight: 500;
}
.l_tra .l_cm_30 img{
height: 80px;
}
@media (max-width: 400px) {
.l_tra .l_cm_30 img{
height: 56px;
}
}
@media (min-width: 410px) {
.l_tra .l_cm_30 img{
height: 60px;
}
.l_tra .l_cm_30 .l_cm_30_t{
font-size: 14px;
margin-top: 6px;
}
}
@media (min-width: 600px) {
.l_tra .l_cm_30 img{
height: 80px;
}
}
.l_tra .left-b-40{
width: 100%;
margin: 7px 0px;
height: 30px;
padding-left: 40px;
}
.l_tra .left-b-40 .left-c-40{
width: 40px;
height: 30px;
float: left;
/* text-align: center; */
line-height: 30px;
position: absolute;
left:4%;
}
.l_tra .left-b-40 .left-g-40{
height: 30px;
float: left;
/* text-align: center; */
line-height: 30px;
width: 95%;
}
.l_tra .left-b-40 .left-c-70{
width: 88px;
font-size: 14px;
height: 30px;
float: left;
text-align: center;
line-height: 30px;
}
.l_tra .left-b-40 .left-g-40 input{
border: 0px solid #D0D0D0;
height: 28px;
float: left;
margin: 0px;
padding: 0px;
font-size: 14px;
}
.l_tra .left-b-40 .left-c-90{
width: 80px;
border-right: 1px solid #D0D0D0;
height: 30px;
float: left;
text-align: center;
line-height: 30px;
position: absolute;
}
.l_tra .left-b-40 .left-g-90{
border: 0px solid #D0D0D0;
height: 30px;
float: left;
margin-left: 80px;
line-height: 30px;
}
.l_tra .left-b-40 .left-g-90 input{
border: 0px solid #D0D0D0;
height: 28px;
float: left;
margin: 0px;
font-size: 14px;
}
.topheight
{
margin-top:14px;
width:100%;
height:30px;
background-color:#2A2E2D;
-webkit-transition: all 0.5s ease;
-moz-transition: all 0.5s ease;
transition: all 0.5s ease;
}
.topheight p
{
font-family:"黑体";
text-align: center;
color:#fff;
font-size:17px;
line-height:32px;
}
.dixbox{
width:100%;
padding-top:5px;
}
.wenbenyudaikuang{
width:100%;
padding-top:5px;
}
.neirongtongy{
width:92%;
height:44px;
padding-left:25px;
border-bottom:1px solid rgba(0,0,0,0.05);
overflow: hidden;
display: flex;
align-items: center; /* 垂直 */
/* justify-content: center; 水平 */
}
.topboxdiv{
width:30%;
height:40px;
float: left;
text-align: center;
}
.topboxdiv p{
line-height:36px;
color:rgba(0,0,0,0.66);
font-family: "黑体";
font-size:16px;
letter-spacing:1px;
}
.butnboxdiv{
width:60%;
/* float: left; */
height:40px;
display: inline-block;
border:1px solid #dddddd;
border-radius:5px;
background-color:#fff;
margin-left: 4%;
}
.butnboxdiv input{
height:38px;
}
.touxiangdian{
width:100%;
height:156px;
background-color:rgba(0,0,0,0.8);
padding-top:20px;
margin-top:45px;
-webkit-transition: all 0.3s ease;
-moz-transition: all 0.3s ease;
transition: all 0.3s ease;
}
.touxdian{
width:85px;
height:85px;
border-radius:100px;
margin-left: auto;
margin-right: auto;
overflow: hidden;
-webkit-transition: all 0.3s ease;
-moz-transition: all 0.3s ease;
transition: all 0.3s ease;
}
.touxdian img{
width:100%;
height:100%;
}
.textbox{
width:100%;
height:40px;
text-align: center;
margin-top:4px;
overflow: hidden;
-webkit-transition: all 0.3s ease;
-moz-transition: all 0.3s ease;
transition: all 0.3s ease;
}
.textbox p{
line-height:32px;
color:rgba(255,255,255,0.9);
-webkit-transition: all 0.3s ease;
-moz-transition: all 0.3s ease;
transition: all 0.3s ease;
font-size:19px;
font-family: "黑体";
font-weight:600;
}
.bianbeir{
width:100%;
padding-left:10px;
padding-right:10px;
-webkit-transition: all 0.3s ease;
-moz-transition: all 0.3s ease;
transition: all 0.3s ease;
overflow: hidden;
background-color:rgba(0,0,0,0.76);
margin-top:-1px;
}
.neikuang{
width:50%;
height:72px;
padding-top:5px;
float: left;
}
.minlimg{
width:100%;
height:32px;
text-align: center;
margin-top:10%;
}
.minlimg img{
width:32px;
}
.textboxp{
width:100%;
height:26px;
text-align: center;
}
.textboxp p{
line-height:30px;
color:rgba(255,255,255,0.85);
font-family: "黑体";
font-size:16px;
}
.bodyboxshiy{
width:100%;
height:100%;
overflow: auto;
/*display: none;
opacity:0;*/
}
.gongzhangxinxitianxie{
width:100%;
height:100%;
padding-top:10px;
}
.quedingquxiao{
width:100%;
height:46px;
}
.quedingquxiao div{
width:100%;
height: 46px;
float: left;
text-align:center;
}
.lefttianxiebox{
background-color:rgba(0,0,0,.12);
}
.righttianxiebox{
background-color:rgba(0,0,0,.78);
width:80%;
margin-left: auto;
margin-right: auto;
border-radius:5px;
overflow: hidden;
height:46px;
text-align: center;
}
.lefttianxiebox p{
color:rgba(0,0,0,.78);
font-family: "黑体";
line-height:48px;
font-size:18px;
letter-spacing:1px;
}
.righttianxiebox p{
color:rgba(255,255,255,.9);
font-family: "黑体";
line-height:44px;
font-size:18px;
letter-spacing:1px;
}
.gerenjianj{
height:90px;
}
.shenfenzbyn{
font-family: "黑体";
font-size:19px;
letter-spacing:1px;
color:rgba(0,0,0,0.3);
}
.imgboxsy{
background-color:rgba(0,0,0,0.05);
width:300px; height:210px;
margin-left: auto;
margin-right: auto;
margin-top:10px;
border-radius:5px;
text-align: center;
}
#cropper-example-1 {
background-color: #000000;
height: 93%;
width: 100%;
position: absolute;
}
.divbut {
width: 100%;
text-align: center;
position: fixed;
z-index:999;
bottom: 0px;
background-color: #000000;
height: 7.5%;
line-height: 50px;
}
.divbut>div:first-child {
float: left;
width: 20%;
}
.divbut>div:last-child {
float: right;
width: 20%;
}
.shugang{
height:60%;
width:2px;
background-color:rgba(255,255,255,0.1);
position:absolute;
margin-left:48%;
margin-top:25px;
}
.imgboxsy img{
width:100%;
height:100%;
}
.bianjikuan{
width:100%;
height:80px;
margin-top:30px;
}
.mui-col-xs-3,
.mui-control-content {
overflow-y: auto;
height: 100%;
}
.mui-segmented-control .mui-control-item {
line-height: 50px;
width: 100%;
}
.mui-segmented-control.mui-segmented-control-inverted .mui-control-item.mui-active {
background-color: #fff;
}
.mui-bar-nav~.mui-content {
padding-top: 44px;
overflow: auto;
background-color: #e9e9ef;
}
.fg-v{
width: 100%;height: 44px;
}
.fg-v .tit_v{
text-align: center;
float: left;width: 74px;line-height: 44px;
}
.fg-v .con_v{
width: 100%;padding-left: 78px;
}
.left_img{
height: 105px;
border: 1px solid #D3D3D3;
width: 90px;
float: left;
margin-top: 5px;
}
.left_img img{
max-width: 140px;
max-height: 105px;
}
.nomeno{
display: block
}
.nomeno1{
display: none
}
.nomeno2{
display: inline-flex
}
/* 弹框样式 */
.modal-mask {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
background: #000;
opacity: 0.5;
overflow: hidden;
z-index: 9000;
color: #fff;
}
.modal-dialog {
width: 90%;
overflow: hidden;
position: fixed;
top: 50%;
left: 0;
z-index: 9999;
background: #fff;
margin: -180rpx 55rpx;
}
.modal-title {
padding-left: 30rpx;
padding-top: 15rpx;
font-size: 26rpx;
color: #030303;
float: left;
}
.modal-content {
padding: 15rpx 25rpx;
}
.btn{
margin-left: 2px;
}
.table {
border-right: 0;
border-bottom: 0;
width: 98%;
}
.l_title .l_title_td_n{
width: 40%;
border-bottom: 0px solid #B6B6B6;
float: left;
height: 25px;
font-size: 13px;
text-align: center;
line-height: 50px;
color: #a0a0a0;
}
.l_title{
height: 44px;
}
.l_title .l_title_td{
width: 30%;border-bottom: 1px solid #dddddd;height: 25px;float: left;
}
.text_t{
border-bottom: 1px solid #dddddd;
}
.text_t_li{
margin-top: 10px;
margin-bottom: 10px;
}
最后就是引用的js UPNG.js pako.js (本来想复制代码的由于内容超出发布限制 你们可以上网搜(百度网盘))