前端图像处理(二)

news2024/12/28 22:28:35

目录

一、上传

1.1、文件夹上传以及进度追踪

1.2、拖拽上传

1.3、图片裁剪上传原理

二、图片布局

2.1、渐进式图片

2.2、图片九宫格

2.3、轮播图(Js)

2.3.1、3D动画轮播图

2.3.2、旋转切换的轮播图

2.4、卡片移入+翻转效果

2.5、环绕式照片墙

一、上传

1.1、文件夹上传以及进度追踪

效果展示:

交互:如何选择多个文件?如何选择文件夹?如何拖拽文件和文件夹?

网络:如何实现多文件上传?如何实现进度追踪?如何实现取消上传?

  • 上传逻辑uploadFile 函数创建一个 XMLHttpRequest 对象,设置请求方法和 URL,并打开请求。它使用 FormData 来包含要上传的文件。
  • 进度追踪:通过监听 xhr.upload.onprogress 事件,可以追踪上传进度,上传进度的计算依赖于 event.lengthComputable 属性
  • 取消上传uploadFile 函数返回一个取消函数,当调用这个函数时,它会调用 xhr.abort() 来取消上传。
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .container {
        border: 1px solid black;
        width: 50%;
        height: 300px;
      }
    </style>
  </head>
  <body>
    <div class="container"></div>
    <script>
      const div = document.querySelector(".container");
      div.ondragenter = (e) => {
        e.preventDefault();
      };
      div.ondragover = (e) => {
        e.preventDefault();
      };
      div.ondrop = (e) => {
        e.preventDefault();
        const items = e.dataTransfer.items;
        for (const item of items) {
          // item 是 DataTransferItem 对象
          const entry = item.webkitGetAsEntry(); // 拿到 FileEntry 对象
          processEntry(entry);
        }
      };
      // 使用递归处理拖放的文件和文件夹
      function processEntry(entry) {
        if (entry.isFile) {
          // 处理文件:拿到 File 文件
          entry.file((file) => {
            uploadFile(file);
          });
        } else if (entry.isDirectory) {
          // 处理文件夹:文件夹中的文件 File 文件对象
          const reader = entry.createReader();
          reader.readEntries((entries) => {
            entries.forEach((entry) => {
              processEntry(entry); // 递归处理每个条目
            });
          });
        }
      }
      function uploadFile(file) {
        const formData = new FormData();
        formData.append("file", file);
        const xhr = new XMLHttpRequest();
        xhr.open("POST", "https://jsonplaceholder.typicode.com/posts/", true);
        // 上传进度追踪
        xhr.upload.onprogress = (event) => {
          if (event.lengthComputable) {
            const percentComplete = (event.loaded / event.total) * 100;
            console.log(`Upload progress:${percentComplete}%`); //fetch无法追踪请求进度
          }
        };
        // 上传完成
        xhr.onload = () => {
          if (xhr.status === 200) {
            console.log("Upload completed");
          } else {
            console.log("Upload error");
          }
        };
        // 上传错误
        xhr.onerror = () => {
          console.log("Upload error");
        };
        // 发送请求
        xhr.send(formData);
        // 返回取消函数
        return () => {
          xhr.abort(); //取消上传
        };
      }
    </script>
  </body>
</html>

1.2、拖拽上传

画一个盒子,盒子里放个上传的input,主要就是看在外界图片直接拖拽进盒子时,要如何处理。

      doms.ondragenter = (e) => {
        e.preventDefault();
        e.target.classList.add("draging");
      };
      doms.ondragover = (e) => {
        e.preventDefault();
      };
      doms.ondrop = (e) => {
        e.preventDefault();
        e.target.classList.remove("draging");
        const files=e.dataTransfer.files
        const types=e.dataTransfer.types
        console.log("FileList数据",files,"文件类型",types)
      };

1.3、图片裁剪上传原理

  <body>
    <input type="file" />
    <img class="preview" />
    <button>上传裁剪后的结果</button>
    <script>
      const inp = document.querySelector("input");
      const img = document.querySelector("img");
      inp.onchange = (e) => {
        const file = e.target.files[0];
        const reader = new FileReader();
        reader.onload = (e) => {
          img.src = e.target.result;
        };
        reader.readAsDataURL(file);
      };
    //   假设已经拿到剪裁后的结果
      function uploadResult({ cutWidth, cutHeight, cutX, cutY }) {
        const cvs = document.createElement("canvas");
        const ctx = cvs.getContext("2d");
        cvs.width = 200;
        cvs.height = 200;
        ctx.drawImage(
          img,
          cutX,
          cutY,
          cutWidth,
          cutHeight,
          0,
          0,
          cvs.width,
          cvs.height
        );
        document.body.appendChild(cvs);
      }
      const btn = document.querySelector("button");
      btn.onclick = () => {
        uploadResult({
          cutWidth: 200,
          cutHeight: 200,
          cutX: 100,
          cutY: 100,
        });
      };
    </script>
  </body>

二、图片布局

2.1、渐进式图片

【场景】加载大图:一开始是模糊的图片,慢慢变的清晰

UI可以给出一张jpg【支持多帧】:第一帧模糊小图,第二帧高清大图,给不了就自己写:

这个组件在使用时直接传入图片即可!

<template>
  <div class="progressive">
    <img :src="placeholder" class="img placeholder" />
    <img :src="origin" class="img origin" @load="handleLoaded" />
  </div>
</template>
<script>
export default {
  // placeholder:模糊小图   origin:原始大图
  props: ['placeholder', 'origin'],
  methods: {
    handleLoaded(e) {
      e.target.parentElement.classList.add('loaded')
    }
  }
}
</script>
<style scoped>
.progressive {
  position: relative;
}
.img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  transition: 0.6s;
}
.origin {
  opacity: 0;
  position: absolute;
  left: 0;
  top: 0;
  /* 给 .origin 图像应用一个模糊效果 */
  filter: blur(10px);
}
.loaded .origin {
  opacity: 1;
  /* 移除模糊效果,使图像变得清晰 */
  filter: blur(0);
}
</style>

2.2、图片九宫格

    <style>
      /* 每个图片都是500 * 500 的 */
      .img-box {
        width: 500px;
        border: 1px solid red;
      }
      .img-container {
        height: 500px;
        display: grid;
        grid-template-columns: repeat(3, 1fr);
      }
      .img-item {
        box-shadow: inset 0 0 0 5px #fff;
        transition: 0.5s;
        background-size: 500px 500px;
        background-image: url(./001.png);
        background-position: var(--bgx, 0) var(--bgY, 0);
        transform: translate(var(--disX, 0), var(--disY, 0));
      }
      .img-container:hover .img-item {
        box-shadow: inset 0 0 0 0 #fff;
      }
    </style>
  <body>
    <div class="img-box">
      <div class="img-container">
        <div class="img-item"></div>
        <div class="img-item"></div>
        <div class="img-item"></div>
        <div class="img-item"></div>
        <div class="img-item"></div>
        <div class="img-item"></div>
        <div class="img-item"></div>
        <div class="img-item"></div>
        <div class="img-item"></div>
      </div>
    </div>
    <script>
      const items = document.querySelectorAll(".img-item");
      for (let i = 0; i < items.length; i++) {
        const r = Math.floor(i / 3); // 行索引
        const c = i % 3; // 列索引
        const bgX = -c * (500 / 3) + "px"; // 背景X位置
        const bgY = -r * (500 / 3) + "px"; // 背景Y位置
        // 位移限制在容器内
        const disX = c; // 水平位移
        const disY = r; // 垂直位移
        items[i].style.setProperty("--bgx", bgX);
        items[i].style.setProperty("--bgY", bgY);
        items[i].style.setProperty("--disX", disX + "px");
        items[i].style.setProperty("--disY", disY + "px");
      }
    </script>
  </body>

2.3、轮播图(Js)

2.3.1、3D动画轮播图

   <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      .carousel-box {
        width: 65%;
        height: 80vh;
        background-color: black;
        position: relative;
        perspective: 1000px; /* 添加透视效果 */
        transform-style: preserve-3d; /* 保持3D变换 */
      }
      .carousel-box span {
        font-size: 40px;
        color: aqua;
        cursor: pointer;
      }
      .carousel-item {
        position: absolute;
        left: 30%;
        top: 30%;
        transform: translate(-50%, -50%) translateZ(0); /* 使用translateZ添加3D效果 */
        transition: transform 0.1s;
      }
      .prev-btn {
        position: absolute;
        left: 10px;
        top: 50%;
        transform: translateY(-50%);
        z-index: 99;
      }
      .next-btn {
        position: absolute;
        right: 10px;
        top: 50%;
        transform: translateY(-50%);
        z-index: 99;
      }
    </style>
  <body>
    <div class="carousel-box">
      <span class="prev-btn">《</span>
      <span class="next-btn">》</span>
      <img src="https://picsum.photos/id/41/400/300/" class="carousel-item" />
      <img src="https://picsum.photos/id/42/400/300/" class="carousel-item" />
      <img src="https://picsum.photos/id/43/400/300/" class="carousel-item" />
      <img src="https://picsum.photos/id/44/400/300/" class="carousel-item" />
      <img src="https://picsum.photos/id/45/400/300/" class="carousel-item" />
      <img src="https://picsum.photos/id/46/400/300/" class="carousel-item" />
      <img src="https://picsum.photos/id/47/400/300/" class="carousel-item" />
      <img src="https://picsum.photos/id/48/400/300/" class="carousel-item" />
      <img src="https://picsum.photos/id/49/400/300/" class="carousel-item" />
      <img src="https://picsum.photos/id/50/400/300/" class="carousel-item" />
    </div>
    <script>
      const items = document.querySelectorAll(".carousel-item");
      let index = 3; //当前显示的图片索引
      function layout() {
        const offsetStep = 100; //每两张图片之间的偏移量
        const scaleStep = 0.5; //每两张图片之间的缩放比例差
        const opacityStep = 0.5; //每两张图片之间的透明度差
        for (let i = 0; i < items.length; i++) {
          const item = items[i];
          const dis = Math.abs(i - index);
          const sign = Math.sign(i - index);
          let xOffset = (i - index) * offsetStep;
          if (i != index) {
            xOffset = xOffset + 100 * sign;
          }
          const scale = scaleStep ** dis;
          const rotateY = 45 * -sign; // 增加旋转角度
          item.style.transform = `translateX(${xOffset}px) scale(${scale}) rotateY(${rotateY}deg)`;
          const opacity = opacityStep ** dis;
          item.style.opacity = opacity;
          const zIndex = items.length - dis; //层级
          item.style.zIndex = zIndex;
        }
      }
      layout();
      const prev = document.querySelector(".prev-btn");
      const next = document.querySelector(".next-btn");
      prev.addEventListener("click", function () {
        index--;
        if (index < 0) {
          index = items.length - 1;
        }
        layout();
      });
      next.addEventListener("click", function () {
        index++;
        if (index > items.length - 1) {
          index = 0;
        }
        layout();
      });
      items.forEach((item, i) => {
        item.addEventListener("click", function (event) {
          event.preventDefault(); // 阻止默认行为,即不触发下载
          index = i;
          layout();
        });
      });
    </script>
  </body>

2.3.2、旋转切换的轮播图

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="styles.css" />
</head>
<body>
  <div class="container">
    <div class="inner">
      <img src="https://picsum.photos/id/51/600" alt="">
      <img src="https://picsum.photos/id/52/600" alt="">
      <img src="https://picsum.photos/id/53/600" alt="">
      <img src="https://picsum.photos/id/54/600" alt="">
      <img src="https://picsum.photos/id/55/600" alt="">
      <img src="https://picsum.photos/id/56/600" alt="">
    </div>
  </div>
</body>
</html>

styles.scss文件:

@use "sass:math";
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
body {
  background-color: black;
}
$size: 200px;
$n: 6;
$pDeg: 360deg / $n;
$r: $size/2;
$R: $r/math.sin($pDeg/2);
$innerSize: $R * 2;
.container {
  width: $size;
  height: $size;
  outline: 5px solid #fff;
  border-radius: 50%;
  margin: 50px auto;
  display: flex;
  justify-content: center;
  overflow: hidden;
}
.inner {
  width: $innerSize;
  height: $innerSize;
  border-radius: 50%;
  // background-color: #f40;//基于红色圈在转:父元素去掉overflow: hidden可以查看原理
  flex-shrink: 0;
  margin-top: $r;
  position: relative;
  img {
    width: $size;
    height: $size;
    border-radius: 50%;
    position: absolute;
    left: 50%;
    margin-left: -$size/2;
    top: -$r;
    transform-origin: center #{$r + $R};
    @for $i from 1 through $n {
      &:nth-child(#{$i}) {
        transform: rotate($pDeg * ($i - 1));
      }
    }
  }
}
$u: 1 / $n * 100%;
$stopPercent: 0.6 * $u;
@keyframes moving {
  @for $i from 1 through $n {
    $p: $u * $i;
    $deg: $pDeg * $i;
    #{$p - $stopPercent},
    #{$p} {
      transform: rotate(-$deg);
    }
  }
}
.inner {
  animation: moving 10s infinite;
}

2.4、卡片移入+翻转效果

移入:从平面变成3D翻起来效果

 <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      body {
        width: 100vw;
        height: 100vh;
        margin: 0;
        display: flex;
        justify-content: center;
        align-items: center;
      }
      .card {
        width: 428px;
        height: 475px;
        margin: 0 50px;
        transform: translateY(-50%);
        position: relative;
      }
      .card img {
        width: 100%;
        position: absolute;
        transition: 0.5s;
      }
      .card .cover {
        z-index: 1;
      }
      .card:hover .cover {
        box-shadow: 0 35px 35px -8px rgb(0, 0, 0, 0.75);
        transform: perspective(500px) rotateX(25deg);
      }
      .card .title {
        z-index: 3;
        bottom: 0;
        right: 0;
      }
      .card:hover .title {
        transform: perspective(500px) translate3d(0, -25px, 50px);
      }
      .card .hero {
        z-index: 2;
        opacity: 0;
      }
      .card:hover .hero {
        opacity: 1;
        transform: perspective(500px) translate3d(0, -50px, 50px);
      }
    </style>
  <body>
    <div class="card">
      <img src="./images/ping.png" alt="" class="cover" />
      <img src="./images/wenzi.png" alt="" class="title" />
      <img src="./images/liqilai.png" alt="" class="hero" />
    </div>
  </body>

翻转:一张卡片展示正面,翻转后看到另一面

  <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      .card {
        perspective: 500px; /* 给父元素设置透视效果 */
        transform-style: preserve-3d; /* 保证子元素的 3D 变换效果生效 */
        width: 200px; /* 设置宽度和高度,确保翻转效果可以看到 */
        height: 300px;
        position: relative; /* 确保子元素的定位 */
      }
      .card .face,
      .card .back {
        position: absolute; /* 确保两张图片在同一位置 */
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        backface-visibility: hidden; /* 隐藏背面的图片 */
        transition: transform 0.6s; /* 加入过渡效果 */
      }
      .card .face {
        transform: rotateY(0deg); /* 正面显示 */
      }
      .card .back {
        transform: rotateY(180deg); /* 背面显示 */
      }
      .card:hover .face {
        transform: rotateY(-180deg); /* 当悬停时,翻转正面 */
      }
      .card:hover .back {
        transform: rotateY(0deg); /* 背面正向显示 */
      }
    </style>
  <body>
    <div class="card">
      <img src="./images/zheng.png" alt="" class="face" />
      <img src="./images/bei.jpg" alt="" class="back" />
    </div>
  </body>

2.5、环绕式照片墙

使用sass

下载:npm install -g sass

编译:sass styles.scss styles.css

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <div class="ring">
      <img src="https://picsum.photos/id/41/400/600/" alt="" />
      <img src="https://picsum.photos/id/42/400/600/" alt="" />
      <img src="https://picsum.photos/id/43/400/600/" alt="" />
      <img src="https://picsum.photos/id/44/400/600/" alt="" />
      <img src="https://picsum.photos/id/45/400/600/" alt="" />
      <img src="https://picsum.photos/id/46/400/600/" alt="" />
      <img src="https://picsum.photos/id/47/400/600/" alt="" />
      <img src="https://picsum.photos/id/48/400/600/" alt="" />
      <img src="https://picsum.photos/id/49/400/600/" alt="" />
      <img src="https://picsum.photos/id/50/400/600/" alt="" />
    </div>
    <script>
      const ring = document.querySelector(".ring");
      let angle = 0;
      // 创建定时器变量
      let intervalId = null;
      function rotateRing() {
        intervalId = setInterval(() => {
          // 每次增加10度
          angle += 10;
          // 如果角度达到或超过360度,重置为0
          if (angle >= 360) {
            angle = 0;
          }
          ring.style.transform = `rotateY(${angle}deg)`;
        }, 100); // 每100毫秒执行一次
      }
      // 开始旋转
      rotateRing();
      // 监听鼠标点击事件,停止旋转
      document.addEventListener("click", () => {
        clearInterval(intervalId); // 停止定时器
      });
    </script>
  </body>
</html>
// ======================styles.scss文件===================
@use "sass:math";
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
html {
  overflow: hidden;
}
body {
  background-color: black;
  perspective: 2000px;
}
$imgWidth: 300px;
$imgHeight: 400px;
$n: 10; // 总的图片数量
$pDeg: 360deg / $n; // 每个图片的角度间隔
$r: 500px; // 半径
.ring {
  width: 100vw;
  height: 100vh;
  position: relative;
  transform-style: preserve-3d;
  img {
    position: absolute;
    width: $imgWidth;
    height: $imgHeight;
    left: 50%;
    top: 50%;
    margin-left: calc(-1 * #{$imgWidth} / 2);
    margin-top: calc(-1 * #{$imgHeight} / 2);
    backface-visibility: hidden;
    opacity: 0.5;
    transition: .5s;
    &:hover {
      opacity: 1;
    }
    // 使用循环将图片分布到圆形轨迹上
    @for $i from 1 through $n {
      &:nth-child(#{$i}) {
        $deg: $pDeg * ($i - 1); // 当前图片的角度
        $x: math.sin($deg) * $r; // 计算 X 坐标
        $z: math.cos($deg) * $r; // 计算 Z 坐标
        transform: translate3d($x, 0, $z) rotateY(180deg + $deg);
      }
    }
  }
}
// 已知:
// sin(θ)= 对边/斜边
// cos(θ)= 邻边/斜边

备注:旋转切换的轮播图和环绕式照片墙案例都用scss进行了计算,编译:sass styles.scss styles.css查看css代码,明显减少了代码,后面将分享scss的相关属性和方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2267130.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

3.BMS系统原理图解读

一、BMS电池板 (1)电池的连接关系&#xff1a;串联 (2)采样控制点&#xff1a;CELL0 - CELL5 (3)端子P1和P3&#xff1a;BAT和BAT- (4)开关S1&#xff1a;控制充放电回路的机械开关 二、BMS控制板 (1)主控MCU 电源 复位 晶振 (2)LED指示灯&#xff1a;4电量指示 1调试指…

用于汽车碰撞仿真的 Ansys LS-DYNA

使用 Ansys LS-DYNA 进行汽车碰撞仿真汽车碰撞仿真 简介 汽车碰撞仿真是汽车设计和安全工程的一个关键方面。这些仿真使工程师能够预测车辆在碰撞过程中的行为&#xff0c;从而有助于改进安全功能、增强车辆结构并符合监管标准。Ansys LS-DYNA 是一款广泛用于此类仿真的强大工具…

使用Java和不同HTTP客户端库发送各种Content-Type类型请求

1. 引言 在HTTP协议中&#xff0c;Content-Type头用于指示请求或响应中数据的媒体类型。了解和正确设置Content-Type 对于确保客户端和服务器之间正确解析数据至关重要。本文将介绍如何使用Java 和 不同的HTTP客户端发送各种Content-Type 类型的请求。 2. 常见的Content-Type…

YOLO11改进-注意力-引入自调制特征聚合模块SMFA

本篇文章将介绍一个新的改进机制——SMFA&#xff08;自调制特征聚合模块&#xff09;&#xff0c;并阐述如何将其应用于YOLOv11中&#xff0c;显著提升模型性能。随着深度学习在计算机视觉中的不断进展&#xff0c;目标检测任务也在快速发展。YOLO系列模型&#xff08;You Onl…

【单片机通讯协议】—— 常用的UART/I2C/SPI等通讯协议的基本原理与时序分析

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、通信基本知识1.1 MCU的参见外设1.2 通信的分类按基本的类型从传输方向上来分 二、UART&#xff08;串口通讯&#xff09;2.1 简介2.2 时序图分析2.3 UART的…

Docker 部署 plumelog 最新版本 实现日志采集

1.配置plumelog.yml version: 3 services:plumelog:#此镜像是基于plumelog-3.5.3版本image: registry.cn-hangzhou.aliyuncs.com/k8s-xiyan/plumelog:3.5.3container_name: plumelogports:- "8891:8891"environment:plumelog.model: redisplumelog.queue.redis.redi…

Empire Lupin One靶机

靶机 ip&#xff1a;192.168.152.157 我们访问页面 第一步信息收集 我们先扫描一下端口 扫描到开启了 22 端口 80 端口 我们使用御剑扫描一下网站的后台 我们挨个访问一下 发现 apache 的帮助页面&#xff0c;暂时记录&#xff0c;看看等会有没有需要 我们查看到 robots.tx…

WPF 绘制过顶点的圆滑曲线(样条,贝塞尔)

项目中要用到样条曲线&#xff0c;必须过顶点&#xff0c;圆滑后还不能太走样&#xff0c;捣鼓一番&#xff0c;发现里面颇有玄机&#xff0c;于是把我多方抄来改造的方法发出来&#xff0c;方便新手&#xff1a; 如上图&#xff0c;看代码吧&#xff1a; -------------------…

绝美的数据处理图-三坐标轴-散点图-堆叠图-数据可视化图

clc clear close all %% 读取数据 load(MyColor.mat) %读取颜色包for iloop 1:25 %提取工作表数据data0(iloop) {readtable(data.xlsx,sheet,iloop)}; end%% 解析数据 countzeros(23,14); for iloop 1:25index(iloop) { cell2mat(table2array(data0{1,iloop}(1,1)))};data(i…

hdfs命令(三)- hdfs 管理命令(三)- hdfs dfsadmin命令

文章目录 前言一、hdfs分布式文件系统管理命令1. 介绍2. 语法及解释3. 命令3.1 生成HDFS集群的状态报告3.1.1 语法及解释3.1.2 示例 3.2 重新加载配置文件并更新NameNode中的节点列表3.3 刷新指定DataNode上的NameNode信息3.3.1 语法 3.4 获取并显示指定DataNode的信息3.4.1 语…

Word论文交叉引用一键上标

Word论文交叉引用一键上标 1.进入Microsoft word使用CtrlH快捷键或单击替换按钮 2.在查找内容中输入[^#] 3.鼠标点击&#xff0c;标签为“替换为&#xff1a;”的文本框&#xff0c;注意光标一定要打在图红色方框圈中的文本框中&#xff01; 4.点击格式选择字体 5.勾选上标…

JAVA:最简单多线程方法调用

以下介绍在JAVA中&#xff0c;最简单调用多线程的方法。 在需要使用多线程方法的类中&#xff0c;新增线程类Thread并实现方法run。 //定义多线程class ThreadLinePoints extends Thread{private String m;public ThreadLinePoints(){}public ThreadLinePoints(String m){this…

Hadoop中MapReduce过程中Shuffle过程实现自定义排序

文章目录 Hadoop中MapReduce过程中Shuffle过程实现自定义排序一、引言二、实现WritableComparable接口1、自定义Key类 三、使用Job.setSortComparatorClass方法2、设置自定义排序器3、自定义排序器类 四、使用示例五、总结 Hadoop中MapReduce过程中Shuffle过程实现自定义排序 一…

科技云报到:人工智能时代“三大件”:生成式AI、数据、云服务

科技云报到原创。 就像自行车、手表和缝纫机是工业时代的“三大件”。生成式AI、数据、云服务正在成为智能时代的“新三大件”。加之全球人工智能新基建加速建设&#xff0c;成为了人类社会数字化迁徙的助推剂&#xff0c;让新三大件之间的耦合越来越紧密。从物理世界到数字世…

Windows 11 中部署 Linux 项目

一、总体思路 在 Windows 11 中部署 Linux 项目&#xff0c;主要是借助 Windows Subsystem for Linux&#xff08;WSL&#xff09;来实现。在WSL中新建基于Linux的项目虚拟环境&#xff0c;以供WIN下已克隆的项目使用。WSL 允许在 Windows 系统上运行原生的 Linux 二进制可执行…

【ETCD】【实操篇(十五)】etcd集群成员管理:如何高效地添加、删除与更新节点

etcd 是一个高可用的分布式键值存储&#xff0c;广泛应用于存储服务发现、配置管理等场景。为了确保集群的稳定性和可扩展性&#xff0c;管理成员节点的添加、删除和更新变得尤为重要。本文将指导您如何在etcd集群中处理成员管理&#xff0c;帮助您高效地维护集群节点。 目录 …

数据结构与算法Python版 平衡二叉查找树AVL

文章目录 一、平衡二叉查找树二、AVL树测试三、AVL树-算法分析 一、平衡二叉查找树 平衡二叉查找树-AVL树的定义 AVL树&#xff1a;在key插入时一直保持平衡的二叉查找树。可以利用AVL树实现抽象数据类型映射Map。与二叉查找树相比&#xff0c;AVL树基本上与二叉查找树的实现…

【Redis】Redis 安装与启动

在实际工作中&#xff0c;大多数企业选择基于 Linux 服务器来部署项目。本文演示如何使用 MobaXterm 远程连接工具&#xff0c;在 CentOS 7 上安装和启动 Redis 服务&#xff08;三种启动方式&#xff0c;包括默认启动、指定配置启动和开机自启&#xff09;。在安装之前&#x…

通过Js动态控制Bootstrap模态框-弹窗效果

目的&#xff1a;实现弹出窗、仅关闭弹窗之后才能操作&#xff08;按ESC可退出&#xff09;。自适应宽度与高度、当文本内容太多时、添加滚动条效果。 效果图 源码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8">…

el-table合并单元行后的多选框选中问题

问题描述 合并单元行以后&#xff0c;首列的多选框也会合并&#xff0c;此时选中该多选框其实是只选中了合并单元行的第一行的多选框&#xff0c;其他的都未被选中。 解决方案 原本想着手动去修改表头的半选状态和全选状态 &#xff0c;但是没有找到相关方法&#xff0c;后面觉…