1. 程式人生 > >MUI 上傳圖片

MUI 上傳圖片

  時隔上次寫部落格有個把月了,主要最近一段時間上班很忙,加上帶娃,各種雜碎的事情繁多,一下子一天一下子一週一下子一個月就過去了,心中也有愧疚,所以為什麼說奮鬥要在30歲前,因為那時候你最年輕,有活力,有時間,有精力,沒房貸,沒車貸,沒孩子,沒老婆,父母年輕,一天到晚出了上班沒點P事,如果能回到五年前,說實話,我也想改變點生活狀態,比如去健身,去旅行,還有大把的時間學習新知識,否則,就只能像我一樣,現在有了鬥志的心,卻每天被柴米油鹽的瑣事困擾著,有些朋友會說,都是你自己給自己找藉口,責任這種東西怎麼說,你去付了,就是有責任感,你去負了,就是沒責任感,看個人吧,至少,我喜歡我的小家庭,疼愛我的老婆,小女兒,我希望能陪她們,等到女兒睡了,基本時間就不多了,你說可以熬夜,也是個人問題吧,我有乙肝大三陽,病毒指數也是8次方級別的,醫生也建議不要熬夜,我也希望健康第一位,所以,所以,哈哈哈,家家有本難唸的經,好了,閒扯幾句,反正都不認識,反正只是瞎bb,說正事。

  除去前面一些個人原因,這次這麼久更新,主要是因為這次的功能是上傳頭像,其實就是上傳圖片,這個功能在任何web開發或者是app開發都是至關重要的,導致,這裡面有許多坑,我也是花了好久,查了好多資料,才順利解決,而且你的技術選型不一樣,導致很多程式碼不一樣,網上資料也非常少,走了不少彎路,開心的是,還是解決了,還是那句老話,之所以貼程式碼,只是為了幫助那些需要的人,我相信在這個地球的某處還是有人被一樣的問題困擾,或者說沒有我那麼幸運找到最終解決方案,所以自己記錄,順便做做善事。

  先說邏輯吧,上傳圖片(或者上傳檔案,邏輯類似),既然我們使用的是MUI+SPRING MVC,首先我們要考慮的是,前臺如何上傳,我考慮過兩種方式,第一種就是前臺將圖片轉換成BASE64編碼,然後mui.post直接傳送到後臺,後臺解析BASE64編碼的圖片,儲存,這種方法理論是可行的,缺點很明顯,你上傳的圖片要足夠小,不然那個BASE64的編碼能噁心死你,所以我直接說第二種方法,就是使用H5的upload方法,位元組流的方式上傳圖片,後臺按位元組流接收圖片。當然為了考慮圖片上傳效率,和使用價效比,我們在上傳前,進行壓縮。程式碼如下:

//點選頭像,彈出【拍照,從相簿選擇】,因為用到很多H5的函式,則在plusReady裡執行
			mui.plusReady(function(){
				
				 // 上傳檔案  
    var filepath;
    var newUrlAfterCompress; 
    
    
				imgdiv.addEventListener('tap',function(){
				  if(mui.os.plus){
            var a=[{
                title:'拍照'
            },{
                title:'從手機相簿選擇'
            }];
            plus.nativeUI.actionSheet({
                title:'修改頭像',
                cancel:'取消',
                buttons:a
            },function(b){
                switch(b.index){
                    case 0:
                        break;
                    case 1:
                        //拍照
                        getImages();
                        break;
                    case 2:
                        //開啟相簿
                        galleryImages();
                        break;
                    default:
                        break;
                }
            },false);   
        }
    });

    //拍照
    function getImages(){
        var mobileCamera=plus.camera.getCamera();
        mobileCamera.captureImage(function(e){
            plus.io.resolveLocalFileSystemURL(e,function(entry){
                var path=entry.toLocalURL()+'?version='+new Date().getTime();
               // console.log("camera:"+path);
                var dstname="_downloads/"+getUid()+".jpg";//設定壓縮後圖片的路徑  
                compressImage(path,dstname,0);
               // filepath = newUrlAfterCompress;
                
            },function(err){
                console.log("讀取拍照檔案錯誤");
            });
        },function(e){
            console.log("er",err);
        },function(){
            filename:'_doc/head.png';
        });
    }
    //從本地相簿選擇
    function galleryImages(){
        console.log("你選擇了從相簿選擇");
        plus.gallery.pick(function(a){
            plus.io.resolveLocalFileSystemURL(a,function(entry){
                plus.io.resolveLocalFileSystemURL('_doc/',function(root){
                    root.getFile('head.png',{},function(file){
                        //檔案已經存在
                        file.remove(function(){
                            console.log("檔案移除成功");
                            entry.copyTo(root,'head.png',function(e){
                                var path=e.fullPath+'?version='+new Date().getTime();
                                
                                 var dstname="_downloads/"+getUid()+".jpg";//設定壓縮後圖片的路徑  
				                compressImage(path,dstname,270);
				               // filepath = dstname;
				                //upload();
                            },function(err){
                                console.log("copy image fail: ",err);
                            });
                        },function(err){
                            console.log("刪除圖片失敗:("+JSON.stringify(err)+")");
                        });
                    },function(err){
                        //開啟檔案失敗
                        entry.copyTo(root,'head.png',function(e){
                            var path=e.fullPath+'?version='+new Date().getTime();
                            uploadHeadImg(path);
                        },function(err){

                            console.log("上傳圖片失敗:("+JSON.stringify(err)+")");
                        });
                    });
                },function(e){
                    console.log("讀取資料夾失敗:("+JSON.stringify(err)+")");
                });
            });
        },function(err){
            console.log("讀取拍照檔案失敗: ",err);
        },{
            filter:'image'
        });
    };
   
   
   
     // 產生一個隨機數  
            function getUid() {  
                return Math.floor(Math.random() * 100000000 + 10000000).toString();  
            } 
            
            function upload() {  
                
                var task = plus.uploader.createUpload('http://47.96.239.47:8080/yqrcbapp/userInfo/uploadImage', {  
                        method: "POST"  
                    },
                    function(t, status) { //上傳完成  
                        if (status == 200) {
                            console.log(t.responseText);
                            imgdiv.innerHTML = '<img id="userImg" src="'+t.responseText+'"/>';
                              
                        } else {  
                            console.log("上傳失敗:" + status);
                        }  
                    }
                );  
            task.addData('username',username);
                    task.addFile(filepath, {  
                        key:filepath
                    });
                    
                task.start();  
                  
            }  
            
            
            //壓縮圖片,這個比較變態的方法,無法return  
            function compressImage(src,dstname,rotate) {  
                //var dstname="_downloads/"+getUid()+".jpg";  
                plus.zip.compressImage({  
                        src: src,  
                        dst: dstname,  
                        overwrite:true,  
                        quality: 20  ,
                        rotate: rotate
                    },  
                    function(event) {  
                        console.log("Compress success:"+event.target);  
                        filepath =  event.target;  
                        upload();
                    },  
                    function(error) {  
                        console.log(error);  
                       // filepath =  src;  
                        //alert("Compress error!");  
                    });  
                  
            }  
});

前臺上傳了圖片,後臺如何接收呢?每種框架接收方式不一樣,我選擇的是JAVA的MVC框架,所以後臺程式碼如下

@RequestMapping(value="/uploadImage", method=RequestMethod.POST)
	@ResponseBody
	private String uploadImage(HttpServletRequest request){
		String username = (String)request.getParameter("username");
		// 複雜型別的request物件
		MultipartHttpServletRequest mRequest = (MultipartHttpServletRequest) request;
		// 獲取檔名集合放入迭代器
		Iterator<String> files = mRequest.getFileNames();
		while (files.hasNext()) {
			//獲取上傳檔案的物件
			MultipartFile mFile = mRequest.getFile(files.next());
			if (mFile != null) {
		//
	   // String path= "";
	    try {
	        byte[] bytes = mFile.getBytes();
	 
//	        // 當前app根目錄
//	        String rootPath = request.getServletContext().getRealPath("/");
//	 
//	        // 需要上傳的相對地址(application.properties中獲取)
//	        String relativePath = "img";
//	 
//	        // 資料夾是否存在,不存在就建立
//	        File dir = new File(rootPath + File.separator + relativePath);
//	        if (!dir.exists())
//	            dir.mkdirs();
//	       // String fileExtension = getFileExtension(file);
	        String filename1 = mFile.getOriginalFilename();
	        String fileExtension = filename1.substring(filename1.lastIndexOf(".")+1);
//	 
	        // 生成UUID樣式的檔名
	        String filename = java.util.UUID.randomUUID().toString() + "." + fileExtension;
//	 
//	        // 檔案全名
//	        String fullFilename = dir.getAbsolutePath() + File.separator + filename;
//	 
//	       
//	 
//	        // 儲存圖片
//	        File serverFile = new File(fullFilename);
//	        BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(serverFile));
//	        stream.write(bytes);
//	        stream.close();
	        
	        //儲存圖片到圖片OSS伺服器,然後返回訪問地址
	     String endpoint = "http://oss-cn-beijing.aliyuncs.com";
	     // 阿里雲主賬號AccessKey擁有所有API的訪問許可權,風險很高。強烈建議您建立並使用RAM賬號進行API訪問或日常運維,請登入 https://ram.console.aliyun.com 建立RAM賬號。
	     String accessKeyId = "***";
	     String accessKeySecret = "***";
	     String bucketName = "dreamxieimg";
	     String objectName = filename;
	     // 建立OSSClient例項。
	     OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
	     // 上傳檔案。<yourLocalFile>由本地檔案路徑加檔名包括字尾組成,例如/users/local/myfile.txt。
	     ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(bytes));
	     Date expiration = new Date(new Date().getTime() + 3600 * 1000*24);
	     // 生成以GET方法訪問的簽名URL,訪客可以直接通過瀏覽器訪問相關內容。
	     URL url = ossClient.generatePresignedUrl(bucketName,objectName , expiration);
	     
	     // 關閉OSSClient。
	     ossClient.shutdown();
	     
	     Map<String,Object> params = new HashMap<String, Object>();
	     params.put("img", url.toString());
	     params.put("username", username);
	        
	     
	     userInfoService.changeimg(params);
//	 //將圖片訪問路徑儲存在資料庫中
//	        String serverPath = new URL(request.getScheme(), request.getServerName(), request.getServerPort(),
//	                request.getContextPath()).toString();
	        return  url.toString();
	 
	    } catch (Exception e) {
	    	e.printStackTrace();
	       // LOGGER.info("error: {}", e);
	    }
	    
	    }
			}
		return null;
	}

注意幾點,

1.阿里的OSS伺服器提供的jar包可能會與專案jar包衝突,需要自己刪除老版本jar包

2.controller只能用request接收,不能用mutiFile接收

具體的都自己看程式碼吧