uni-app h5 php oss 图片上传

我尼玛uni-app竟然没有支持h5图片上传的组件,呕心沥血的自己写了一个~~

思路:

  • 首先将图片转成base64方式,再利用canvas进行图片压缩,避免图片太大上传超时
  • 提交给后端php处理,由php上传到oss,然后返回路径

效果演示
OSS文档

前端

<template>
	<view>
		<view class="collection-top-interval"></view>
		<view class="collection-view">
			<template>
				<view>
					res
				</view>
				<view class="year">
					<view class="title">
						<text style="">
							图片上传
						</text>
					</view>
					<view class="line1"></view>
					<view class="year-info" style="position: relative;">
						<img src="/static/image/property/add_image.png"  style="width: 150upx;height: 160upx;margin-right: 36upx;" alt="">
						<view v-for="(item,index) in temp_images" :key="index">
							<img @click="preview(index)" :src="item"  style="width: 150upx;height: 160upx;" alt="">
							<img @click="delImg(index)" src="/static/image/property/error.png" style="position: relative;bottom:140upx;right: 24upx;width: 36upx;height: 36upx;">
						</view>
						<view ref="inputfile" id="inputfile" style="position: absolute; opacity: 0; "></view>  
					</view>
				</view>
				<view class="collection-top-interval"></view>
				<button class="confirm" @click="next()">完成</button>
			</template>
		</view>
	</view>
</template>
<script>
	export default {
		components: {
		},
		data() {
			return {
				temp_images : [],
				driving_license : [],
				compulsory_insurance : [],
				res : '',
				baseUrl : '',
				isIOS : false
			};
		},
		onShow(){
		},
		mounted() {  
			let myself = this;
			//创建一个input上传框
            var input = document.createElement('input')  
            input.type = 'file'
			input.multiple = 'multiple';
            input.onchange = (e) => {
				let inputDOM = document.getElementById("inputfile");
				//获取input元素
				inputDOM = inputDOM.firstChild;
				// 通过eDOM取文件数据
				for(var i = 0;i < inputDOM.files.length;i++){
					this.file  = inputDOM.files[i];
					//new一个FileReader实例
					let reader = new FileReader();
					reader.readAsDataURL(this.file)  //base 64读取
					reader.onload=function(e){
						//最多上传三张,你可以自己定义
						if(myself.temp_images.length < 3){
							//this.result 就是base64图片地址,对图片进行压缩
							myself.compress(this.result,800,1).then(function (val) {
								//压缩后的图片
								var baseUrl = val;
								uni.showLoading({
								    title: '加载中'
								});
								//将图片转交给后端处理
								uni.request({
									url: 'https://your_domain.com/api.php/yearly/upload',
									method: 'POST',
									data: {
										value : baseUrl,
									},
									success: res => {
										uni.hideLoading();
										res = res.data;
										if(res.code == 1){
											myself.driving_license.push(res.data);
											myself.temp_images.push(baseUrl);
										}
										uni.showToast({
											title: res.msg,
											duration: 1000,
											icon: 'none'
										});
									},
									fail: (res) => {
										myself.res = res;
									},
									complete: () => {}
								});
							});
						}
					}
				}
            }  
			//将input追加到view中
            this.$refs.inputfile.$el.appendChild(input);  
			var inputfile =  document.getElementById("inputfile");
			inputfile = inputfile.firstChild;
			inputfile.style.width = '63px';
			inputfile.style.height = '63px';
        },
		computed: {
		},
		onLoad(e) {
			this.isIOS = !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
		},
		methods: {
			//利用canvas对图片进行压缩
			compress(base64String, w, quality) {
				var myself = this;
				var getMimeType = function (urlData) {
					var arr = urlData.split(',');
					var mime = arr[0].match(/:(.*?);/)[1];
					return mime;
				};
				
				var newImage = new Image();
				var imgWidth, imgHeight;
		 
				var promise = new Promise(resolve => newImage.onload = resolve);
				newImage.src = base64String;
				return promise.then(() => {

					imgWidth = newImage.width;
					imgHeight = newImage.height;

					var canvas = document.createElement("canvas");
					var ctx = canvas.getContext("2d");
					if (Math.max(imgWidth, imgHeight) > w) {
						if (imgWidth > imgHeight) {
							canvas.width = w;
							canvas.height = w * imgHeight / imgWidth;
						} else {
							canvas.height = w;
							canvas.width = w * imgWidth / imgHeight;
						}
						//如果是安卓客户端的话,将图片分辨率*2
						if(!myself.isIOS){
							canvas.height = canvas.height * 2;
							canvas.width = canvas.width * 2;
						}
					} else {
						canvas.width = imgWidth;
						canvas.height = imgHeight;
					}
					ctx.clearRect(0, 0, canvas.width, canvas.height);
					ctx.drawImage(newImage, 0, 0, canvas.width, canvas.height);
					var base64 = canvas.toDataURL(getMimeType(base64String), quality);
					return base64;
				});
			},
			preview(index) {
			  uni.previewImage({
				  current : index,
				  urls : this.temp_images
			  })
			},
			goBack() { 
				uni.navigateBack({
					delta: 1
				});
			},
			delImg(index){
				uni.showLoading({
					title: '加载中'
				});
				uni.request({
					url: 'https://your_domain.com/api.php/yearly/delImage',
					method: 'POST',
					data: {
						img_url : this.driving_license[index].split("com/")[1],
					},
					success: res => {
						uni.hideLoading();
						res = res.data;
						if(res.code == 1){
							this.temp_images.splice(index,1);
							this.driving_license.splice(index,1);
						}
						uni.showToast({
							title: res.msg,
							duration: 1000,
							icon: 'none'
						});
					},
					fail: (res) => {
						myself.res = res;
					},
					complete: () => {}
				});
			}
		}
	};
</script>

<style lang="scss">
	@import "./index.css";	

</style>

CSS

.collection-top-interval {
	height: 13px;
	width: 100%;
	background-color: #f0f0f0;
	margin-top:0upx;
}

.collection-view {
	position: relative;
	font-family: PingFang-SC-Bold;
}

.line{
	padding: 0px !important;
	margin: 0px !important;
	height:1px;
	width: 100%;
	background:rgba(238,238,238,1);
}

.line1{
	padding: 0px !important;
	margin-left: 24upx;
	width:702upx !important;
	height:1px;
	background:rgba(238,238,238,1);
}

.year{
	display: flex;
	flex-direction: column;
}

.year>view{
	margin-left: 20upx;
	padding: 40upx 0upx;
	display: flex;
	flex-direction: row;
	position: relative;
	width: 100%;
}

input{
	border: 0px;
	display: flex;
	flex-direction: row;
	justify-content: flex-start;
}

.title text{
	width:300upx;
	height:31upx;
	font-size:32upx;
	font-family:PingFang SC;
	font-weight:bold;
	color:rgba(51,51,51,1);
	line-height:30upx;
}

.year-info>text{
	height:27upx;
	font-size:28upx;
	font-family:PingFang SC;
	font-weight:500;
	color:rgba(51,51,51,1);
	line-height:27upx;
	float: left;
}

.confirm{
	width:750upx;
	height:108upx;
	line-height: 108upx;
	border-radius: 0px;
	background:rgba(255,72,0,1);
	font-family:PingFang SC;
	font-weight:500;
	color:rgba(255,255,255,1);
	margin-top: 20upx;
	position: fixed;
	bottom: 0px;
}

.add-one{
	width: 127upx !important;
	height: 127upx !important;
}

PHP

    public function upload(){
		//实例化oss类
        $Oss = new Oss();
		//获取base64地址
        $value = input('value');
        $reg = '/data:image\/(\w+?);base64,(.+)$/si';
		//获取文件后缀名
        preg_match($reg,$value,$match_result);
        $file_name = date('YmdHis').$this->codeMaking().'.'.$match_result[1];
		//上传到oss的目录
        $logo_path =  'uploads/yearly/'.date('Ymd');
        //开始上传
        $result = $Oss->putObject(base64_decode($match_result[2]),$logo_path,$file_name);
        $this->success('成功',str_replace('http','https',$result['info']['url']));
    }

    public function delImage(){
		//获取需要删除的文件
        $img_url = input('img_url');
        $Oss = new Oss();
		//开始删除
        $result = $Oss->delObject($img_url);
        $this->success('成功');
    }

OSS类


use OSS\OssClient;
use OSS\Core\OssException;
use OSS\Core\OssUtil;

class Oss
{
    private $ossClient;
    private $bucket;

    function __construct(){
        $config = config('aliyun_oss_config');
        $this->ossClient = new OssClient($config['accessKeyId'],$config['accessKeySecret'],$config['endpoint']);
        $this->bucket = $config['bucket'];
    }

    /**
     * 上传内存中的内容
     * @param $tmp_name
     * @param $path
     * @param $file_name
     * @return null
     * @throws OssException
     */
    public function putObject($tmp_name,$path,$file_name){
        $result = $this->ossClient->putObject($this->bucket, $path.'/'.$file_name, $tmp_name);
        return $result;
    }

    public function delObject($img_url){
        $result = $this->ossClient->deleteObject($this->bucket,$img_url);
        return $result;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值