JQ+vue实现图片拼接(无限套娃版)

2 篇文章 0 订阅
1 篇文章 0 订阅
css样式

   /* css初始化 */
        
        * {
            margin: 0;
            padding: 0;
        }
        /* 去掉li的小圆点 */
        
        li {
            list-style: none;
        }
        /* 去掉a的下划线 */
        
        a {
            text-decoration: none;
        }
        /* 搜索框去除边框 */
        
        input,
        button,
        select {
            border: 0;
            /* 设置背景颜色为透明 */
            background-color: transparent;
            /* 去掉外轮廓 */
            outline: none;
        }
        /* em和i标签字体样式 */
        
        em,
        i {
            font-style: normal;
        }
        /* 图片的空白间隙 */
        
        img {
            vertical-align: middle;
        }
        /* 清除浮动 */
        
        .clearfix:after {
            content: '';
            display: block;
            height: 0;
            clear: both;
            visibility: hidden;
        }
        /* 左浮动 */
        
        .fl {
            float: left;
        }
        /* 右浮动 */
        
        .fr {
            float: right;
        }
        
        body {
            background-color: #000;
            color: #fff;
        }
        
        .lay-box {
            display: flex;
        }
        
        .lay-left {
            flex: 0.5;
            margin-top: 2%;
            margin-top: 2%;
        }
        
        .lay-center {
            flex: 2.3;
            display: flex;
            align-items: center;
            justify-content: center;
            margin-top: 10%;
            position: relative;
            flex-direction: column;
            min-height: 500px;
        }
        
        .lay-center-top {
            display: flex;
            width: 100%;
            height: 100%;
        }
        
        .lay-center-bottom {
            width: 100%;
            display: flex;
            justify-content: space-around;
            align-items: center;
            z-index: 1000000;
        }
        
        .lay-right {
            display: flex;
            flex-direction: column;
            flex: 0.2;
            margin-top: 2%;
            z-index: 100000;
        }
        
        .automatic,
        .manual {
            background-color: #22AF90;
            text-align: center;
            padding: 10px 0px;
            border-radius: 5px;
            width: 100%;
            cursor: pointer;
        }
        
        .automatic {
            margin-bottom: 20px;
        }
        
        .lay-centers {
            display: flex;
        }
        
        .lay-center-left,
        .lay-center-right {
            width: 100%;
            height: 100%;
        }
        
        .lay-center-leftimg,
        .lay-center-rightimg {
            width: 100%;
            height: 100%;
        }
        
        .lay-ui {
            display: flex;
        }
        
        .lay-left-contont .lay-ui .choice {
            margin-right: 10px;
        }
        
        .choiceclose {
            margin-right: 10px;
        }
        
        .choiceImg {
            width: 30%;
            height: 30%;
        }
        
        .lay-left-top {
            margin-bottom: 20px;
        }
        /*加载的样式*/
        
        .box {
            border-radius: 4px;
            height: 20px;
            width: 170px;
            background: #ebebeb;
            position: relative;
        }
        
        .box .line {
            background: rgb(92, 151, 4);
            height: 20px;
            text-indent: 999px;
        }
        
        .title {
            font-size: 18px;
            color: #000;
            margin-bottom: 20px;
        }
        
        .loadding {
            position: fixed;
            width: 14%;
            height: 12%;
            background: #fff;
            top: 50%;
            left: 50%;
            margin-top: -6%;
            margin-left: -7%;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            z-index: 1000;
        }
        
        #canvas {
            position: absolute;
            display: none;
        }
        
        #que,
        .clear,
        #undo {
            background-color: #22AF90;
            text-align: center;
            padding: 10px 0px;
            border-radius: 5px;
            width: 10%;
            cursor: pointer;
            display: none;
        }
        
        #imgnewtwo {
            display: none;
        }
        
        .lay-join-box {
            margin-top: 2%;
        }
        
        .lay-joint {
            display: flex;
            margin-top: 1%;
        }
        
        .error {
            margin-bottom: 50px;
            font-size: 18px;
        }
html结构
     <div class="loadding">
        <div class="title">正在拼接中,请稍后...</div>
        <div class="box">
            <div class="line" data-load="100"></div>
        </div>
    </div>
    <div class="lay-box" id='laybox'>
        <div class="lay-left">
            <div class="lay-left-contont">
                <!--默认展示的图片-->
                <div class="lay-ui" v-for="(item,index) in regList" :key='index'>
                    <input type="checkbox" class="choice" name="img" :data="item.imgurl" @click="specifiName(item.imgurl,item.imgdata)" :uid="item.imgdata">
                    <img :src="item.imgurl" alt="" class='choiceImg'>
                </div>
                <!--拼接后的图片-->
                <div class='lay-join-box'>
                    <div class='joint-title'>已拼接</div>
                    <div class="lay-joint" v-for="(item,index) in jointList" :key='index'>
                        <input type="checkbox" class="choice" name="img" :value="index" :data="item.imgurl" :uid="item.uid" :oid="item.oid" @click="specifiName(item.imgurl,item.uid)">
                        <img :src="item.imgurl" alt="" class='choiceImg'>
                        <button class="error" @click="clean(item.oid,index,item.uid)">×</button>
                    </div>
                </div>


            </div>
        </div>
        <div class="lay-center" id='laycenter'>
            <div class='lay-center-top' id="laycentertop">
                <canvas id="canvas" ref='canvas' @click="main($event)"></canvas>
                <!--手动拼接-->
                <div class="lay-centers" id="imgnewone">
                    <div class="lay-center-left" v-for="item in imgList">
                        <img :src="item" alt="" class='lay-center-leftimg'>
                    </div>
                </div>

                <!--自动拼接-->
                <div class="lay-center-left" id="imgnewtwo">
                    <!--手动拼接展示的图片-->
                    <img :src="bilgurl" alt="" class='lay-center-leftimg' id="manimg">
                    <!--自动拼接展示的图片-->
                    <img :src="bilgurlzi" alt="" class='lay-center-leftimg' id="autoimg">
                </div>
            </div>
            <div class='lay-center-bottom'>
                <button id="que" @click="determine">确定</button>
                <button class="clear" @click="clear">取消</button>
                <button id="undo" :disabled='prohibit' @click="redo">撤销</button>
            </div>


        </div>
        <div class="lay-right">
            <button class='automatic' @click="Automatic">自动拼接</button>
            <button class='manual' @click="Manual($event)">手动拼接</button>
        </div>
    </div>
js代码
<script>
        $(document).ready(function() {
            //全局定义的数组
            var newList = []
                //全局数组(保存拼接图再拼接的标识)
            var prohibit = []
            var hid = 0
                //自定义的id前缀
            var prefix = 'H'


            // 加载
            var step = 1, //加载基数
                status = 100, //加载步骤数
                $line = $('.line'),
                $lineVal = $line.text(),
                $attrVal = $line.data('load'), //进度条属性值
                $number = parseInt($('.numb').text()),
                $numberVal = parseFloat($number / status); //进度数值

            $line.css('width', $lineVal + '%'); //出事进度值

            function watchFn() {
                var self = $(this);
                var showVal = $attrVal / status;

                var numberHtml = parseInt($numberVal * step);

                //数值小于10让其显示小数点后面一位
                if ($number < 10) {
                    numberHtml = parseFloat($numberVal * step).toFixed(1);
                }

                //设置进度条、进度数值的样式/内容
                $line.css('width', showVal * step + '%');
                $('.numb').html(numberHtml);

                //基数大于步骤数清空定时器
                if (step >= status) {
                    clearInterval(timer);
                }

                step += 1;
            }
            //定时器,每个步骤15毫秒
            var timer = setInterval(watchFn, 60);

            // vue部分
            var app = new Vue({
                el: '#laybox',
                data: function() {
                    return {
                        regList: [], //默认展示的数组
                        //自动配准的数组
                        jointList: [], //拼接后的数组
                        checkboxId: [], //选中的复选框的id
                        imgList: [],
                        checkboxList: [], //选中的值
                        // 配准代码
                        clicks: 0,
                        lastClick: [0, 0],
                        //算法的坐标
                        coordinateA: [],
                        coordinateB: [],
                        // 撤销的数组
                        undoHistoryA: [],
                        a: {},
                        b: {},
                        prohibit: true,
                        x: 0,
                        y: 0,
                        trigter: true,
                        //自动配准的计时器
                        timer: null,
                        // 手动配准的计时器
                        timers: null,
                        //手动的接口图片
                        bilgurl: '',
                        //自动的接口图片
                        bilgurlzi: '',
                        ash: false, //是否置灰
                        jointObj: {}, //放置拼接的对象
                        checkObj: {}, //放置没有
                        numIndex: null,
                    }
                },
                mounted() {
                    this.regList = JSON.parse(localStorage.getItem("SplicList"))
                    $('.loadding').hide()
                },
                methods: {
                    //自动拼接的数据
                    specifiName(item, id) {
                        //自动配准的数组
                        this.checkboxList.push(item)
                        this.checkboxId.push(id)
                    },
                    //清除
                    clean(oid, index, uid) {
                        var res = prohibit.find(item => {
                            return item == uid
                        })
                        if (res == uid) {
                            alert('无法进行删除')
                            return false
                        } else {
                            //自动拼接
                            //对应的下标
                            this.numIndex = index
                                //取出当前删除的图片oid,并进行对比
                            var newArr = oid.split('-')
                                //操作uid
                            var reelect = $("input[name='img']")
                            for (var i = 0; i < reelect.length; i++) {
                                if (reelect[i].checked == true) {
                                    for (var j = 0; j < newArr.length; j++) {
                                        if (reelect[i].getAttribute('uid') == newArr[j]) {
                                            reelect[i].disabled = false
                                            reelect[i].checked = false
                                        }
                                    }
                                }
                            }
                            //删除数组元素
                            this.jointList.forEach((item, index) => {
                                    if (this.numIndex === index) {
                                        this.jointList.splice(this.numIndex, 1)
                                    }
                                })
                                //全局保存的数组赋值
                            prohibit = prohibit.filter(function(item) {
                                return item == uid
                            })

                        }


                        //判断是否要清空其他元素
                        if (this.jointList.length == 0) {
                            this.bilgurlzi = ''
                            this.bilgurl = ''
                            $('#autoimg').hide()
                            $('#manimg').hide()
                        }

                        //手动拼接
                    },
                    //自动配准
                    Automatic() {
                        $('#imgnewone').hide()
                        if (this.checkboxList.length < 2) {
                            alert('请选择两张图片')
                            return false
                        } else {
                            //置灰的判断
                            var reelect = $("input[name='img']")
                            for (var i = 0; i < reelect.length; i++) {
                                if (reelect[i].checked == true) {
                                    reelect[i].disabled = true
                                }
                            }

                            var canvas = document.getElementById("canvas")
                            context = canvas.getContext('2d');
                            context.clearRect(0, 0, canvas.width, canvas.height);
                            $('.loadding').show()
                                //自动配准接口
                            var newimg = ''
                            var newCheck = this.checkboxId
                            var imgNUm1 = this.checkboxList[0]
                            var imgNUm2 = this.checkboxList[1]
                            var imgNUm3 = this.checkboxList[2]
                            var imgNUm4 = this.checkboxList[3]
                            var imgNUm5 = this.checkboxList[4]
                            var imgNUm6 = this.checkboxList[5]
                            hid++
                            $.ajax({
                                type: "GET",
                                url: "http://www.nb.cn/Remote/Index/imageMosaic",
                                async: false,
                                data: {
                                    fisrtImage: imgNUm1,
                                    secondImage: imgNUm2,
                                    thirdImage: imgNUm3,
                                    fourthImage: imgNUm4,
                                    fifthImage: imgNUm5,
                                    sixthImage: imgNUm6
                                },
                                success: function(ret) {
                                    newimg = ret.data.fusion_image
                                    newCheck.forEach(item => {
                                            if (item && item.indexOf('H') === 0) {
                                                prohibit.push(item)
                                            }
                                        })
                                        // hid的值 uid
                                    let jointObj = {
                                        imgurl: newimg,
                                        oid: newCheck.join('-'),
                                        uid: prefix + hid,
                                    }
                                    newList.push(jointObj)
                                    setTimeout(() => {
                                        $('.loadding').hide()
                                        $('#manimg').hide()
                                        $('#autoimg').show()
                                        $('#imgnewtwo').show()
                                    }, 800)
                                },
                            });
                            this.jointList = newList
                            this.checkboxId = []
                            this.checkboxList = []
                            this.jointList.forEach((item, index) => {
                                this.bilgurlzi = this.jointList[index].imgurl
                            });
                        }

                    },
                    //手动配准
                    Manual(e) {
                        $('#imgnewtwo').hide()
                        if (this.checkboxList.length != 2) {
                            alert('请选择两张图片')
                            return false
                        } else {
                            $('#que').show()
                            $('.clear').show()
                            $('#undo').show()
                            $('#canvas').show()
                            this.imgList = this.checkboxList
                            $('#imgnewone').show()
                            var canvas = document.querySelector('#canvas')
                            canvas.width = $('#laycenter').width()
                            canvas.height = $('#laycenter').height()
                        }
                    },
                    getCursorPosition(e) {
                        if (e.pageX != undefined && e.pageY != undefined) {
                            var rect = canvas.getBoundingClientRect();
                            this.x = e.clientX - rect.left * (canvas.width / rect.width);
                            this.y = e.clientY - rect.top * (canvas.height / rect.height);

                        }
                        return [this.x, this.y];
                    },
                    drawLine(e) {
                        var canvas = document.getElementById("canvas")
                        context = canvas.getContext('2d');
                        context.beginPath();
                        this.x = this.getCursorPosition(e)[0];
                        this.y = this.getCursorPosition(e)[1];
                        context.strokeStyle = '#f0f0f0';
                        if (this.trigter == true) {
                            const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
                            const compressed = pako.deflate(new Uint8Array(imageData
                                .data));
                            this.undoHistoryA.push(compressed);
                            this.trigter = false
                        }
                        context.arc(this.x, this.y, 2, 0, 2 * Math.PI)
                        context.stroke();


                        if (this.clicks != 1) {
                            this.clicks++;

                        } else {
                            context.moveTo(this.lastClick[0], this.lastClick[1]);
                            context.lineTo(this.x, this.y, 6);
                            context.strokeStyle = '#f0f0f0';
                            context.stroke();
                            this.clicks = 0;
                        }
                        this.lastClick = [this.x, this.y];
                        if (this.clicks == 0) {
                            const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
                            const compressed = pako.deflate(new Uint8Array(imageData
                                .data));
                            this.undoHistoryA.push(compressed);
                            this.prohibit = false
                            var x = this.x
                            var y = this.y
                            this.b = {
                                x,
                                y
                            }
                            this.coordinateB.push(this.b)

                        } else {

                            var x = this.x
                            var y = this.y
                            this.a = {
                                x,
                                y
                            }
                            this.coordinateA.push(this.a)
                        }
                    },
                    main(e) {
                        var canvas = document.getElementById('canvas')
                        this.drawLine(e)
                    },
                    redo() {
                        // 撤销
                        {
                            this.undoHistoryA.pop();
                            const compressed = this.undoHistoryA[this.undoHistoryA.length - 1]
                            this.coordinateA.pop()
                            this.coordinateB.pop()

                            try {
                                const decompressed = pako.inflate(compressed); // 解压
                                const uint8ClampedArray = new Uint8ClampedArray(decompressed);
                                const imageData = new ImageData(uint8ClampedArray, canvas.width, canvas
                                    .height);

                                context.putImageData(imageData, 0, 0);
                            } catch (error) {
                                console.error(error);
                            }
                            if (this.undoHistoryA.length === 0) {
                                this.prohibit = true;
                            }


                        }
                    },
                    determine() {
                        //置灰的判断
                        var reelect = $("input[name='img']")
                        for (var i = 0; i < reelect.length; i++) {
                            if (reelect[i].checked == true) {
                                reelect[i].disabled = true
                            }
                        }
                        if (this.coordinateA.length < 4 || this.coordinateB.length < 4) {
                            alert('最少标注四条线段')
                            return false
                        }
                        var imgNUm1 = this.imgList[0]
                        var imgNUm2 = this.imgList[1]
                        var newimg = ''
                        var newCheck = this.checkboxId
                        hid++
                        $('.loadding').show()
                        $.ajax({
                            type: "GET",
                            url: "http://www.nb.cn/Remote/Index/manualSplicing",
                            async: false,
                            data: {
                                fisrtImage: imgNUm1,
                                secondImage: imgNUm2,
                                fixedPoint: this.coordinateA,
                                movedPoint: this.coordinateB
                            },
                            success: function(ret) {
                                newimg = ret.data.fusion_image
                                newCheck.forEach(item => {
                                        if (item && item.indexOf('H') === 0) {
                                            prohibit.push(item)
                                        }
                                    })
                                    // hid的值 uid
                                this.jointObj = {
                                    imgurl: newimg,
                                    oid: newCheck.join('-'),
                                    uid: prefix + hid
                                }
                                newList.push(this.jointObj)
                                setTimeout(() => {
                                    $('.loadding').hide()
                                }, 800)
                            },
                        });

                        // 数组id拼接
                        this.jointList = newList
                        this.jointList.forEach((item, index) => {
                            this.bilgurl = this.jointList[index].imgurl
                        });

                        $('#imgnewtwo').show()
                        $('#imgnewone').hide()
                            //按钮隐藏
                        $('#que').hide()
                        $('.clear').hide()
                        $('#undo').hide()
                        $('#canvas').hide()
                            //图片展示隐藏
                        $('#manimg').show()
                        $('#autoimg').hide()
                        this.checkboxId = []
                        this.checkboxList = []
                        context.clearRect(0, 0, canvas.width, canvas.height);
                    },
                    clear() {
                        var canvas = document.getElementById('canvas')
                        context = canvas.getContext('2d');
                        context.clearRect(0, 0, canvas.width, canvas.height);
                        this.imgList = []
                        $('#que').hide()
                        $('.clear').hide()
                        $('#undo').hide()
                        $('#canvas').hide()
                    }
                }
            })
        });
    </script>

数据可以自行模拟
引入了vue.js jquery.js pako.js

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值