在手機端使用拍照功能上傳圖片的功能的解決文案
主要依賴了一個compress.js的檔案,檔案內容如下:
```
/* * Tencent is pleased to support the open source community by making WeUI.js available. * * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. * * Licensed under the MIT License (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * * * Unless required by applicable law or agreed to in writing, software distributed under the License is * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific language governing permissions and * limitations under the License. *//** * 檢查圖片是否有被壓扁,如果有,返回比率 * ref to http://stackoverflow.com/questions/11929099/html5-canvas-drawimage-ratio-bug-ios */function detectVerticalSquash(img) { // 拍照在IOS7或以下的機型會出現照片被壓扁的bug var data; var ih = img.naturalHeight; var canvas = document.createElement('canvas'); canvas.width = 1; canvas.height = ih; var ctx = canvas.getContext('2d'); ctx.drawImage(img, 0, 0); try { data = ctx.getImageData(0, 0, 1, ih).data; } catch (err) { console.log('Cannot check verticalSquash: CORS?'); return 1; } var sy = 0; var ey = ih; var py = ih; while (py > sy) { var alpha = data[(py - 1) * 4 + 3]; if (alpha === 0) { ey = py; } else { sy = py; } py = (ey + sy) >> 1; // py = parseInt((ey + sy) / 2) } var ratio = (py / ih); return (ratio === 0) ? 1 : ratio;}/** * dataURI to blob, ref to * @param dataURI */function dataURItoBuffer(dataURI){ var byteString = atob(dataURI.split(',')[1]); var buffer = new ArrayBuffer(byteString.length); var view = new Uint8Array(buffer); for (var i = 0; i < byteString.length; i++) { view[i] = byteString.charCodeAt(i); } return buffer;}function dataURItoBlob(dataURI) { var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; var buffer = dataURItoBuffer(dataURI); return new Blob([buffer], {type: mimeString});}/** * 獲取圖片的orientation * ref to */function getOrientation(buffer){ var view = new DataView(buffer); if (view.getUint16(0, false) != 0xFFD8) return -2; var length = view.byteLength, offset = 2; while (offset < length) { var marker = view.getUint16(offset, false); offset += 2; if (marker == 0xFFE1) { if (view.getUint32(offset += 2, false) != 0x45786966) return -1; var little = view.getUint16(offset += 6, false) == 0x4949; offset += view.getUint32(offset + 4, little); var tags = view.getUint16(offset, little); offset += 2; for (var i = 0; i < tags; i++) if (view.getUint16(offset + (i * 12), little) == 0x0112) return view.getUint16(offset + (i * 12) + 8, little); } else if ((marker & 0xFF00) != 0xFF00) break; else offset += view.getUint16(offset, false); } return -1;}/** * 修正拍照時圖片的方向 * ref to */function orientationHelper(canvas, ctx, orientation) { const w = canvas.width, h = canvas.height; if(orientation > 4){ canvas.width = h; canvas.height = w; } switch (orientation) { case 2: ctx.translate(w, 0); ctx.scale(-1, 1); break; case 3: ctx.translate(w, h); ctx.rotate(Math.PI); break; case 4: ctx.translate(0, h); ctx.scale(1, -1); break; case 5: ctx.rotate(0.5 * Math.PI); ctx.scale(1, -1); break; case 6: ctx.rotate(0.5 * Math.PI); ctx.translate(0, -h); break; case 7: ctx.rotate(0.5 * Math.PI); ctx.translate(w, -h); ctx.scale(-1, 1); break; case 8: ctx.rotate(-0.5 * Math.PI); ctx.translate(-w, 0); break; }}/** * 壓縮圖片 */function compress(file, options, callback) { const reader = new FileReader(); reader.onload = function (evt) { if(options.compress === false){ // 不啟用壓縮 & base64上傳 的分支,不做任何處理,直接返回檔案的base64編碼 file.base64 = evt.target.result; callback(file); return; } // 啟用壓縮的分支 const img = new Image(); img.onload = function () { const ratio = detectVerticalSquash(img); const orientation = getOrientation(dataURItoBuffer(img.src)); const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); const maxW = options.compress.width; const maxH = options.compress.height; let w = img.width; let h = img.height; let dataURL; if(w < h && h > maxH){ w = parseInt(maxH * img.width / img.height); h = maxH; }else if(w >= h && w > maxW){ h = parseInt(maxW * img.height / img.width); w = maxW; } canvas.width = w; canvas.height = h; if(orientation > 0){ orientationHelper(canvas, ctx, orientation); } ctx.drawImage(img, 0, 0, w, h / ratio); if(/image/jpeg/.test(file.type) || /image/jpg/.test(file.type)){ dataURL = canvas.toDataURL('image/jpeg', options.compress.quality); }else{ dataURL = canvas.toDataURL(file.type); } if(options.type == 'file'){ if(/;base64,null/.test(dataURL) || /;base64,$/.test(dataURL)){ // 壓縮出錯,以檔案方式上傳的,採用原檔案上傳 console.warn('Compress fail, dataURL is ' + dataURL + '. Next will use origin file to upload.'); callback(file); }else{ let blob = dataURItoBlob(dataURL); blob.id = file.id; blob.name = file.name; blob.lastModified = file.lastModified; blob.lastModifiedDate = file.lastModifiedDate; callback(blob); } }else{ if(/;base64,null/.test(dataURL) || /;base64,$/.test(dataURL)){ // 壓縮失敗,以base64上傳的,直接報錯不上傳 options.onError(file, new Error('Compress fail, dataURL is ' + dataURL + '.')); callback(); }else{ file.base64 = dataURL; callback(file); } } }; img.src = evt.target.result; }; reader.readAsDataURL(file);}export default { compress};
```
檔案中有多種bug處理,如,拍照在IOS7或以下的機型會出現照片被壓扁的bug 、修正拍照時圖片的方向、壓縮圖片等問題。
具體使用也大概說明一下,下例子使用用的是vue-cli
1, 引入 js 注在靜態檔案目錄下,es6引入,,注意,匯出的是物件,,且用的是default匯出
import compress from '@/assets/js/compress.js'
2, 下面是個人的使用方式,
```
<template> <div class="course-picture input_file_wrapper flex-center icon-default-img"> <input type="file" @change="handleFile" name="file" class="input_file"> <span class="course-picture-con" :style="{'background-image':'url('+logoImg+')'}"></span> </div></template><script>import compress from '@/assets/js/exif/compress.js' export default { data(){ return { logoImg : '' } }, props : { logo : { type : String, default : '' }, }, watch :{ logo(val){ this.logoImg = val } }, components : { }, methods : { // 選擇修改圖片事件 handleFile(e) { e.stopPropagation() let _this = this let file = e.target.files[0]; if (!/image/w+/.test(file.type)) { this.$toast('請選擇圖片') return } compress.compress(file,{ compress: { width:520, height:520 } },function (data) { _this.logoImg = data.base64 _this.$emit('change',_this.logoImg) }) }, } } </script><style scoped>.course-picture {height: 2.5rem;width: 2.5rem;}</style>
```
說到這兒,懂些vue的大概就知道了,上面是一個當成元件的封裝,還可以更完善,謝謝點贊。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3402/viewspace-2826050/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 解決android有的手機拍照後上傳圖片被旋轉的問題Android
- 移動端檔案、圖片及拍照上傳
- 用exfe.js和canvas解決移動端 IOS 拍照上傳圖片翻轉問題JSCanvasiOS
- 短視訊app開發,短視訊動態功能上傳圖片時,規定圖片壓縮的大小APP
- 微信小程式開發之從相簿獲取圖片 使用相機拍照 本地圖片上傳微信小程式地圖
- 移動端圖片上傳旋轉、壓縮的解決方案
- PbootCMS上傳圖片變模糊、上傳圖片尺寸受限的解決方案boot
- Android本地圖片上傳(拍照+相簿)Android地圖
- 關於UEditor遠端圖片上傳失敗的解決辦法
- ios手機豎屏拍照圖片旋轉90°問題解決方法iOS
- 獲取本地圖片或拍照,進行頭像圖片的上傳的工具類地圖
- 完美解決fixed在手機端的bug和移動端1px寬度
- android選擇圖片或拍照圖片上傳到伺服器(包括上傳引數)Android伺服器
- IE8.0 上傳圖片時,提示無效的圖片檔案的解決辦法!
- 織夢dedecms圖片集上傳圖片不能上傳 彈出提示302的解決方法
- Android上傳圖片之呼叫系統拍照和從相簿選擇圖片Android
- 解決WordPress文章上傳圖片使用中文名不顯示的問題
- FCKeditor2.2無法使用上傳功能的解決!
- 帝國CMS遠端儲存圖片生成很多重複無效圖片的解決方法
- chrome上傳圖片 路徑為c:/fakepath的解決辦法Chrome
- 專案需求討論 - WebView下拍照及圖片選擇功能WebView
- Win10電腦開機圖片解鎖無法使用的最佳解決方法Win10
- 微信小程式-拍照或選擇圖片並上傳檔案微信小程式
- cropper,圖片剪輯上傳工具的使用
- 求高手解決用java限制上傳圖片大小!!Java
- PbootCMS上傳圖片被壓縮怎麼解決boot
- 直播平臺搭建,Android手機拍照和手機相簿選取圖片的工具Android
- 移動端圖片上傳元件分享元件
- 移動端H5圖片上傳的那些坑H5
- 仿微信圖片選取、相機拍照—PhotoPicker(已整合GalleryView)View
- 巧妙的有css合併圖片解決tab切換的背景圖片CSS
- koa 圖片上傳詳解
- 圖片上傳方案詳解
- 電商圖片線上製作,可摳圖可寫文案
- 我需要在Web上完成一個圖片上傳的功能Web
- Laravel 使用 FastDFS 上傳圖片LaravelAST
- node+express實現圖片上傳功能Express
- 使用Webcam實現拍照功能Web