cnpm install --save vue-cropperjs
import VueCropper from "vue-cropperjs";
components: { VueCropper },
<div class="crop-demo">
<img :src="cropImg" class="pre-img" />
<div v-show="bendiisshowxiugai[0]" class="crop-demo-btn">
{{$t('lang.Click_change_image')}}
<input
class="crop-input"
type="file"
name="image"
ref="head_picture_file"
accept="image/*"
id="change"
@change="setImage"
/>
</div>
</div>
<el-dialog
:title="$t('lang.Crop_Image')"
:visible.sync="dialogVisible"
width="30%"
>
<vue-cropper
ref="cropper"
:src="imgSrc"
:aspect-ratio="cropperAspectWH"
:ready="cropImage"
:zoom="cropImage"
:cropmove="cropImage"
style="width:100%;height:300px;"
></vue-cropper>
<span slot="footer" class="dialog-footer">
<el-button @click="cancelCrop">{{$t('lang.cancel')}}</el-button>
<el-button type="primary" @click="upladPic">{{$t('lang.confirm')}}</el-button>
</span>
</el-dialog>
//以下五條都是截圖插件的 data中的數據
defaultSrc: require("../../../assets/xxx.png"), //默認圖片
fileList: [],
imgSrc: "",
cropImg: "",
dialogVisible: false,
img_size: "",
max_fuyuan_defaultSrc: [],
setImage(e) {
let that = this;
let file = e.target.files[0];
if (!file.type.includes("image/")) {
return;
}
this.reader = "";
let canvas = "";
let ctx = "";
let img = "";
that.imgSrc = "";
this.reader = new FileReader();
this.reader.onload = event => {
if (file.size >= 1024 * 1024 * 1) {
console.log("圖片過大");
var quality = 1; //壓縮圖片的質量
canvas = document.createElement("canvas"); //創建畫布
ctx = canvas.getContext("2d");
img = new Image();
img.src = event.target.result;
img.onload = function() {
const width = img.width;
const height = img.height;
canvas.width = 800; //這里可以自定義你的圖片大小
canvas.height = 800 * (img.height / img.width);
console.log(img.width, img.height, canvas.width, canvas.height); //圖片轉化時打印'data:,'的原因 就是獲取Dom元素img的信息,img onload要比渲染的快,沒能拿到寬高。
//所以在下面的that.imgSrc = canvas.toDataURL("image/jpeg", quality);時出現打印'data:,'的情況
setTimeout(() => { //我的解決方案就是用計時器來延遲獲取寬高以及轉化的操作
ctx.fillRect(0, 0, 0, 0);
ctx.drawImage(img, 0, 0, 800, canvas.height);
that.imgSrc = canvas.toDataURL("image/jpeg", quality); //將圖片轉為Base64 之后預覽要用
that.$refs.cropper &&
that.$refs.cropper[0].replace(that.imgSrc); //第二次壓縮失效的原因和解決方法就是這句。。。 that.$refs.cropper[0].replace(that.imgSrc);
that.dialogVisible = true;
}, 50);
};
} else {
that.dialogVisible = true;
that.imgSrc = event.target.result;
that.$refs.cropper &&
that.$refs.cropper[0].replace(event.target.result);
}
};
that.reader.readAsDataURL(file);
},
cropImage() {
this.cropImg = this.$refs.cropper[0].getCroppedCanvas().toDataURL();
},
cancelCrop() {
this.dialogVisible = false;
this.cropImg = this.max_fuyuan_defaultSrc[
this.max_fuyuan_defaultSrc.length - 1
];
$("#change").val(""); //取消change事件 //第二次選擇相同圖片的時候change事件沒有觸發所以不會彈出彈窗,要先清除 就是這句。。。
},
upladPic() {
this.sumitImageFile(this.cropImg);
this.dialogVisible = false;
},
sumitImageFile(base64Codes) {
$("#change").val(""); //取消change事件
let that = this;
var formData = new FormData();
//convertBase64UrlToBlob函數是將base64編碼轉換為Blob
var picName = new Date().getTime() + ".png"; //給截圖的文件命名
formData.append(
"file",
that.convertBase64UrlToBlob(base64Codes),
picName
); //append函數的第一個參數是后台獲取數據的參數名,和html標簽的input的name屬性功能相同
this.max_fuyuan_defaultSrc.push(this.imgSrc);
if (this.img_size / 1024 / 1024 < 1.5) {
serviceApi.requestPostUploadFile(formData).then(body => {
that.defaultSrc = body.file_name;
// that.cropImg = that.defaultSrc; //截圖用的
});
} else {
this.$message({
message: "要上傳圖片太大!",
type: "warning"
});
this.max_fuyuan_defaultSrc.pop();
// that.imgSrc=that.cropImg=this.max_fuyuan_defaultSrc;
that.imgSrc = that.cropImg = this.max_fuyuan_defaultSrc[
this.max_fuyuan_defaultSrc.length - 1
];
}
},
//將以base64的圖片url數據轉換為Blob
convertBase64UrlToBlob(urlData) {
var bytes = window.atob(urlData.split(",")[1]); //去掉url的頭,並轉換為byte
//處理異常,將ascii碼小於0的轉換為大於0
var ab = new ArrayBuffer(bytes.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i);
}
let size = new Blob([ab], { type: "image/png" });
this.img_size = size.size;
return new Blob([ab], { type: "image/png" });
}
由於時間關系 以上代碼並不完全 僅供參考 下次再發叭。。。
另附我找到的相關的好文章
https://segmentfault.com/q/1010000009665100
https://blog.csdn.net/aithena/article/details/103034718
https://www.thinbug.com/q/16077010
https://stackoverflow.com/questions/40908729/html5-canvas-todataurl-returns-data-in-firefox
http://www.360doc.com/content/18/0928/22/13328254_790527851.shtml
https://www.cnblogs.com/goloving/p/8260206.html
http://www.mamicode.com/info-detail-2151760.html
https://www.jianshu.com/p/f9986bd52ec6
https://blog.csdn.net/qq_36538012/article/details/97984553
我遇到的問題 有的有好幾種可能的原因 可以參考以上的
首先是用this.cropImg 和this.max_fuyuan_defaultSrc保存 從服務器拿到的最開始的默認圖片進行展示和存儲,
然后this.max_fuyuan_defaultSrc 用在這數組保存每次在彈窗里截取之后的圖片,如果點擊取消截取 就返回數組的上一張圖片給this.imgSrc在這里顯示
彈窗每次點開的時候都進行判斷選擇的圖片是不是大於1M 的 如果是就進行壓縮
然后上傳給服務器的時候我又判斷了一下是不是大於1.5M 中間留了保險的空間喲 如果圖片大於1.5M 就又用this.max_fuyuan_defaultSrc進行了回退了