zoukankan      html  css  js  c++  java
  • elementui+vue cropper 裁剪图片封装

    公共裁剪页面

    <style>
        .el-dialog__header {
            padding: 24px 0 11px 28px;
        }
    
        .el-dialog__title {
            color: #333333;
        }
    
        .el-dialog__body {
            padding: 0 28px;
        }
    
        .el-dialog__footer {
            padding: 20px 28px;
        }
    
        .avatar {
            display: flex;
        }
    
        .avatar-left {
            display: flex;
            justify-content: center;
            align-items: center;
            width: 400px;
            height: 400px;
            background-color: #F0F2F5;
            margin-right: 10px;
            border-radius: 4px;
        }
    
        .avatar-left-crop {
            width: 400px;
            height: 400px;
            position: relative;
        }
    
        .crop-box {
            width: 100%;
            height: 100%;
            border-radius: 4px;
            overflow: hidden
        }
    
        .avatar-left-p {
            text-align: center;
            width: 100%;
            position: absolute;
            bottom: 20px;
            color: #ffffff;
            font-size: 14px;
        }
    
        .avatar-right {
            width: 150px;
            height: 400px;
            background-color: #F0F2F5;
            border-radius: 4px;
            padding: 16px 0;
            box-sizing: border-box;
        }
    
        .avatar-right-div {
            border: 3px solid #ffffff;
            border-radius: 50%;
        }
    
        .avatar-right-previews {
            width: 200px;
            height: 200px;
            overflow: hidden;
            border-radius: 50%;
        }
    
        .avatar-right-text {
            text-align: center;
            margin-top: 50px;
            font-size: 14px;
        }
    
        span {
            color: #666666;
        }
    
        .cropper-view-box,
        .cropper-face,
        .preview {
            border-radius: 50%;
        }
    </style>
    <script src="~/Scripts/jquery-3.4.1.min.js"></script>
    <script src="~/Scripts/vue.min.js"></script>
    <script src="~/Scripts/ElementUI/index.js"></script>
    <script src="~/Scripts/ElementUI/locale/en.js"></script>
    <script src="~/Scripts/cropper/cropper.min.js"></script>
    <link href="~/Scripts/cropper/cropper.min.css" rel="stylesheet" />
    <div id="app">
        <div style="display: flex" class="avatar">
            <div class="avatar-left">
                <div v-if="!optionsPhoto.img">
                    @*<el-upload ref="upload"
                                   action=""
                                   style="text-align: center;margin-bottom: 24px"
                                   :on-change="uploads"
                                   accept="image/png, image/jpeg, image/jpg"
                                   :show-file-list="false"
                                   :auto-upload="false">
                            <el-button slot="trigger" size="small" type="primary" ref="uploadBtn">选择图片</el-button>
                        </el-upload>*@
                    <input type="file" id="doc" accept="image/*" v-on:change="CropperSetImagePreview1()" />
                    <div>支持jpg、png格式的图片,大小不超过3M</div>
                </div>
                <div v-show="optionsPhoto.img" class="avatar-left-crop">
                    <div class="col col-6" id="localImag">
                        <img id="image" src="../docs/images/picture.jpg" alt="Picture">
                    </div>
                    <p class="avatar-left-p">
                        鼠标滚轮缩放控制图片显示大小,鼠标拖拽调整显示位置
                    </p>
                </div>
            </div>
            <div class="avatar-right">
                <div class="avatar-right-div" v-for="item in previewsDiv" :style="item.style">
                    <div v-show="optionsPhoto.img" :class="previews.div" class="avatar-right-previews" :style="item.zoomStyle">
                        <div class="preview"></div>
                    </div>
                </div>
                <div class="avatar-right-text">
                    <el-button v-if="optionsPhoto.img" type="text" v-on:click="uploadPreviews">重新上传</el-button>
                    <span v-else>预览</span>
                </div>
            </div>
        </div>
        <span slot="footer" class="dialog-footer">
            <el-button v-on:click="CropDialogVisible=false">取 消</el-button>
            <el-button type="primary" v-on:click="getCrop">确 定</el-button>
        </span>
    </div>
    
    <script>
        function each(arr, callback) {
            var length = arr.length;
            var i;
    
            for (i = 0; i < length; i++) {
                callback.call(arr, arr[i], i, arr);
            }
    
            return arr;
        }
        var cropper;
        $(function () {
            var layerIndex;
            ELEMENT.locale(ELEMENT.lang.en);
            var vue = new Vue({
                el: '#app',
                data: {
                    optionsPhoto: { img: false },
                    CropDialogVisible: false,
                    //实时预览图数据
                    previews: {},
                    previewsDiv: [
                        //108px 预览样式
                        {
                            style: {
                                 '108px',
                                height: '108px',
                                margin: '0 auto'
                            },
                            zoomStyle: {
                                zoom: 0.54
                            }
                        },
                        //68px 预览样式
                        {
                            style: {
                                 '68px',
                                height: '68px',
                                margin: '27px auto'
                            },
                            zoomStyle: {
                                zoom: 0.34
                            }
                        },
                        //48px 预览样式
                        {
                            style: {
                                 '48px',
                                height: '48px',
                                margin: '0 auto'
                            },
                            zoomStyle: {
                                zoom: 0.24
                            }
                        }
                    ]
                },
                methods: {
                    uploadPreviews: function () { },
                    uploads(file) {
                        const isIMAGE = file.raw.type === 'image/jpeg' || file.raw.type === 'image/png';
                        const isLt3M = file.raw.size / 1024 / 1024 < 3;
                        if (!isIMAGE) {
                            this.$message({
                                showClose: true,
                                message: '请选择 jpg、png 格式的图片!',
                                type: 'error',  //提示类型
                            });
                            return false;
                        }
                        if (!isLt3M) {
                            this.$message({
                                showClose: true,
                                message: '上传图片大小不能超过 3MB',
                                type: 'error',  //提示类型
                            });
                            return false;
                        }
                        let reader = new FileReader();
                        reader.readAsDataURL(file.raw);
                        reader.onload = e => {
                            this.optionsPhoto.img = e.target.result //base64
                        }
                    },
                    CropperSetImagePreview: function () {
                        this.CropDialogVisible = true;
                    },
                    CropperSetImagePreview1: function () {
                        var docObj = document.getElementById("doc");
                        console.log(docObj.files)
                        var imgObjPreview = document.getElementById("image");
                        if (docObj.files && docObj.files[0]) {
                            //火狐下,直接设img属性
                            imgObjPreview.style.display = 'block';
                            imgObjPreview.style.maxWidth = '960px';
                            imgObjPreview.style.height = '400px';
                            //imgObjPreview.src = docObj.files[0].getAsDataURL();
                            // 取绝对路径的getAsDataURL
    
                            //火狐7以上版本不能用上面的getAsDataURL()方式获取,需要一下方式
                            imgObjPreview.src = window.URL.createObjectURL(docObj.files[0]);
                        } else {
                            //IE下,使用滤镜
                            docObj.select();
                            var imgSrc = document.selection.createRange().text;
                            var localImagId = document.getElementById("localImag");
                            //必须设置初始大小
                            localImagId.style.maxWidth = "960px";
                            localImagId.style.height = 'auto';
                            //图片异常的捕捉,防止用户修改后缀来伪造图片
                            try {
                                localImagId.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale)";
                                localImagId.filters.item("DXImageTransform.Microsoft.AlphaImageLoader").src = imgSrc;
                            } catch (e) {
                                alert("您上传的图片格式不正确,请重新选择!");
                                return false;
                            }
                            imgObjPreview.style.display = 'none';
                            document.selection.empty();
                        }
    
                        this.changeFile();
                        this.previews.url = window.URL.createObjectURL(docObj.files[0]);
                        this.optionsPhoto.img = true;
                    },
    
                    changeFile: function () {
                        var image = document.querySelector('#image');
                        var previews = document.querySelectorAll('.preview');
                        cropper = new Cropper(image, {
                            aspectRatio: 1,
                            toggleDragModeOnDblclick: false,
                            cropBoxResizable: true,
                            cropBoxMovable: true,
                            highlight: false,
                            center: false,
                            guides: false,
                            restore: false,
                            autoCropArea: 0.65,
                            dragMode: 'move',
                            // movable:false,
                            ready: function () {
                                var clone = this.cloneNode();
                                croppable = true;
                                clone.className = ''
                                clone.style.cssText = (
                                    'display: block;' +
                                    ' 100%;' +
                                    'min- 0;' +
                                    'min-height: 0;' +
                                    'max- none;' +
                                    'max-height: none;'
                                );
                                each(previews, function (elem) {
                                    elem.appendChild(clone.cloneNode());
                                });
                            },
                            // 类型: Function
                            // 默认: null“ cropper” 事件的捷径。
                            crop: function (e) {
                                var data = e.detail;
                                var cropper = this.cropper;
                                var imageData = cropper.getImageData(); //输出图像位置,大小等相关数据。
                                var previewAspectRatio = data.width / data.height;
    
                                each(previews, function (elem) {
                                    var previewImage = elem.getElementsByTagName('img').item(0);
                                    var previewWidth = elem.offsetWidth;
                                    var previewHeight = previewWidth / previewAspectRatio;
                                    var imageScaledRatio = data.width / previewWidth;
    
                                    elem.style.height = previewHeight + 'px';
                                    previewImage.style.width = imageData.naturalWidth / imageScaledRatio + 'px';
                                    previewImage.style.height = imageData.naturalHeight / imageScaledRatio + 'px';
                                    previewImage.style.marginLeft = -data.x / imageScaledRatio + 'px';
                                    previewImage.style.marginTop = -data.y / imageScaledRatio + 'px';
                                });
                            },
    
                        });
    
                    },
                    getRoundedCanvas: function (sourceCanvas) {
                        var canvas = document.createElement('canvas');
                        var context = canvas.getContext('2d');
                        var width = sourceCanvas.width;
                        var height = sourceCanvas.height;
                        canvas.width = width;
                        canvas.height = height;
                        context.imageSmoothingEnabled = true;
                        context.drawImage(sourceCanvas, 0, 0, width, height);
                        context.globalCompositeOperation = 'destination-in';
                        context.beginPath();
                        context.arc(width / 2, height / 2, Math.min(width, height) / 2, 0, 2 * Math.PI, true);
                        context.fill();
                        return canvas;
                    },
                    getCrop: function () {
                        var croppedCanvas;
                        var roundedCanvas;
                        var roundedImage;
    
                        if (!croppable) {
                            return;
                        }
                        // Crop
                        croppedCanvas = cropper.getCroppedCanvas();
                        // Round
                        roundedCanvas = this.getRoundedCanvas(croppedCanvas);
                        // Show
                        roundedImage = document.createElement('img');
                        roundedImage.src = roundedCanvas.toDataURL()
                        blob = this.dataURLtoBlob(roundedCanvas.toDataURL());
    
    
                      //  this.UserInfo.UserPhoto = roundedImage.src;
                        parent.vue.CloseCropPicture(roundedImage.src);
                    },
                    dataURLtoBlob: function (dataurl) {
                        var arr = dataurl.split(','),
                            mime = arr[0].match(/:(.*?);/)[1],
                            bstr = atob(arr[1]),
                            n = bstr.length,
                            u8arr = new Uint8Array(n);
                        while (n--) {
                            u8arr[n] = bstr.charCodeAt(n);
                        }
                        return new Blob([u8arr], {
                            type: mime
                        });
                    },
                },
                mounted: function () {
                
                }
            });
    
        });
    
    </script>

    父页面

                <div class="PP--main-left">
    
                    <template v-if="IsPreview">
                        <img id="image" style="height:214px;214px" :src="UserInfo.UserPhoto" :key="UserInfo.UserPhoto" alt="Picture" />
                    </template>
                    <template v-else>
                        <div class="poto" style="cursor:pointer" v-on:click="CropperSetImagePreview()">
                            <template v-if="UserInfo.UserPhoto==null||UserInfo.UserPhoto==''">
                                <i class="pwc-icon pwc-upload-outline"></i>
                                <span>Upload image</span>
                            </template>
                            <template v-else>
                                <img style="214px;height:214px;" :src="UserInfo.UserPhoto" :key="UserInfo.UserPhoto"></img>
                            </template>
                        </div>
                    </template>
                    <div style="display:none">
    
                        <input type="file" id="file" accept="image/*" v-on:change="UpLoadFile(1)" />
                    </div>
                </div>
     
    
    <div>
            <el-dialog :visible.sync="dialogVisibleCop"
                       width="30%">
                <iframe :src="frameUrlCrop" frameborder="0" width="100%" height="527px"></iframe>
                <span slot="footer" class="dialog-footer">
                </span>
            </el-dialog>
        </div>
    
      CropperSetImagePreview: function () {
                        this.dialogVisibleCop = true;
                        this.frameUrlCrop=rootUrl + "Common/CropPicture"
                    },
                    CloseCropPicture: function (base64Photo) {
                        this.UserInfo.UserPhoto = base64Photo;
                        this.dialogVisibleCop = false;
                    },

    参考文档

    https://blog.csdn.net/XHL1314mmq/article/details/105815966

    https://blog.csdn.net/qq_41389920/article/details/87967539

  • 相关阅读:
    windows 查看某个端口号被占用情况
    C# 配置文件ini操作类
    C#:如何解决WebBrowser.DocumentCompleted事件的多次调用
    什么是异或_异或运算及异或运算的作用
    UID卡、CUID卡、FUID卡的区别
    C#获取窗口大小和位置坐标 GetWindowRect用法
    C#中SetWindowPos函数详解
    C#让电脑发声,播放声音
    C#自动缩进排列代码的快捷键 c# 代码重新排版 变整齐
    安卓手机USB无法共享、上网或卡顿的解决方法
  • 原文地址:https://www.cnblogs.com/happygx/p/14626704.html
Copyright © 2011-2022 走看看