照片无限分裂?

前言:
最近看到一个有趣的视频,一张狗的图片,横着切割后,交叉排列,就变成两只狗了。再竖着切割,就变成了4只狗。这个东西很有趣,所以我就准备来自己实现编程一下这个东西。

演示

照片无限分裂1?

设计

这里我使用canvas来实现这个功能,通过初始化的时候加载一张图片。然后对图片进行横向切割(x轴切割),例如间隔20像素进行切割。切割下来的左边10像素和右边10像素就是两个图片。每次进行这样的切割操作,左边的按照顺序放在一起,右边的也同样。这样进行一次x轴的切割后就会看到图像被切分成了两份,当时整体上变得窄了。然后再上面的方式,从y轴方向进行切割,就会看到图像变成了4份(图像整体的大小是不变的)。这里就这样简单介绍一下了,因为本身也很简单,不过我实现的时候对这个canvas的用法不太熟悉,走了一些弯路。建议先看一下视频,我在B站上传了2个视频,看完视频再看代码,或者自己直接运行一下代码试一试。

注意:这个代码是不能直接打开在浏览器预览的,因为canvas的drawImage不允许跨域操作图片。所以建议使用vscode的 live server 或者其它IDE开启一个静态服务器,通过ip+port的形式访问。如果你想更加简洁一些,那么推荐你:python3 -m http.server

实现

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>dog2dogs</title>
</head>
<body>
    <div style="border: 1px solid red">
        <canvas id="cs" height="600" width="1000"></canvas>
    </div>
    <button id="load" onclick="load()">加载</button>
    <button id="x_split" onclick="x_split()">横切</button>
    <button id="y_split" onclick="y_split()">纵切</button>

    <script>
        let flag = false; // 初始是未加载
        let cs = document.getElementById("cs");
        let ctx = cs.getContext("2d");
        let img = new Image();
        let size = 2;   // 分隔的像素间隔,最小是2.
        let r = {}; // 图片缩放后的宽高属性对象
        img.setAttribute("src", "002.jpg");
        
        img.onload = () => {
            flag = true;   // 设置状态为已经加载
            r = resize(img.width, img.height, cs.height)
        }

        // 绘制原始图像
        function load() {
            if (!flag) {
                alert("图片未加载!")
            }
            ctx.drawImage(img, 0, 0, r.w, r.h);
        }

        function x_split() {
            img_x_split(cs, ctx, r, size);
            // 获取右边横向分割的图片
            let t_img_data = ctx.getImageData(cs.width/2, 0, r.w, r.h);
            // 清除canvas
            ctx.clearRect(0, 0, cs.width, cs.height);  
            // 重新绘制横向分割的图片
            ctx.putImageData(t_img_data, 0, 0)
        }

        function y_split() {
            // 对横向切割图片进行纵向分割
            img_y_split(cs, ctx, r, size);
        }

        function img_x_split(cs, ctx, r, size) {
            for (let i = 0; i < r.w; i=i+size) {
                let left_img_data = ctx.getImageData(i, 0, size/2, r.h);
                let right_img_data = ctx.getImageData(i+size/2, 0, size/2, r.h)  
                ctx.putImageData(left_img_data, cs.width/2+i/2, 0);
                ctx.putImageData(right_img_data, cs.width/2+r.w/2+i/2, 0)     
            }
        }

        function img_y_split(cs, ctx, r, size) {
            for (let i = 0; i < r.h; i=i+size) {
                let up_img_data = ctx.getImageData(0, i, r.w, size/2);
                let down_img_data = ctx.getImageData(0, i+size/2, r.w, size/2)
                ctx.putImageData(up_img_data, cs.width/2, i/2);
                ctx.putImageData(down_img_data, cs.width/2, r.h/2+i/2)
            }
        }


        /*
        图片的resize函数,用来计算缩放图片,
        返回缩放后的宽高
        param: w 图片的宽
               h 图片的高
               ch 画板的高
        */
        function resize(w, h, ch) {
            w = w/h * ch;
            h = ch;
        
            return {
                w: w,
                h: h
            }
        }
    </script>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值