在手機端使用拍照功能上傳圖片的功能的解決文案
主要依賴了一個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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 移動端檔案、圖片及拍照上傳
- input上傳圖片怎樣觸發預設拍照功能?
- 用exfe.js和canvas解決移動端 IOS 拍照上傳圖片翻轉問題JSCanvasiOS
- Android本地圖片上傳(拍照+相簿)Android地圖
- 短視訊app開發,短視訊動態功能上傳圖片時,規定圖片壓縮的大小APP
- PbootCMS上傳圖片變模糊、上傳圖片尺寸受限的解決方案boot
- 織夢dedecms圖片集上傳圖片不能上傳 彈出提示302的解決方法
- chrome上傳圖片 路徑為c:/fakepath的解決辦法Chrome
- 專案需求討論 - WebView下拍照及圖片選擇功能WebView
- 帝國CMS遠端儲存圖片生成很多重複無效圖片的解決方法
- 直播平臺搭建,Android手機拍照和手機相簿選取圖片的工具Android
- cropper,圖片剪輯上傳工具的使用
- PbootCMS上傳圖片被壓縮怎麼解決boot
- 重磅!全新 sib remote 功能上線,iOS 遠端除錯的福音!REMiOS除錯
- AppGallery Connect 移動端App新功能上線APP
- 圖片上傳方案詳解
- koa 圖片上傳詳解
- angular上傳圖片到.netcore後端AngularNetCore後端
- Laravel 使用 FastDFS 上傳圖片LaravelAST
- 解決jenkins 傳送郵件圖片亂碼問題Jenkins
- 解決Hexo關於圖片的問題Hexo
- 移動端使用localResizeIMG4壓縮圖片並上傳
- node+express實現圖片上傳功能Express
- H5 和小程式拍照圖片旋轉、壓縮和上傳H5
- 前端丨如何使用 tcb-js-sdk 實現圖片上傳功能前端JS
- 微信JSSDK上傳圖片過程中編輯圖片描述,解決思路記錄JS
- 仿微信圖片選取、相機拍照—PhotoPicker(已整合GalleryView)View
- 前端圖片解決方案前端
- vue+springboot實現圖片的上傳及回顯失敗問題的解決VueSpring Boot
- 使用Vue實現圖片上傳的三種方式Vue
- PS拍照圖片清晰化處理教程
- Android 拍照及相簿選取圖片功能,已適配Android6.0、7.0、8.0Android
- 使用jpeg圖片庫,顯示圖片並簡單實現LCD的觸屏功能
- Overleaf中插入pdf圖片只顯示圖片路徑的解決方式
- QQ空間無法上傳多張圖片解決方案
- Laravel 使用騰訊雲 cos 進行圖片上傳使用詳解Laravel
- php+html5相容手機端的圖片選取裁剪上傳例項PHPHTML
- 配置Django-TinyMCE元件支援上傳圖片功能Django元件