两张图片进行分析

两张图片进行分析,可以拖动左边图片进行放大、缩小查看图片差异

底图

javascript 复制代码
<template>
   
   <div class="box_container">
    <section>
      <div class="" v-for="item in imgData.imgDataVal" :key="item.id">
        <img :style="{
          width: boxStyle.width + '%',
          top: boxStyle.top,
          left: boxStyle.left,
        }" :src="item.src" :alt="item.name" />

        <div v-if="clickState" class="selectRegion"
          :style="{ top: selectRegionStyle.top, left: selectRegionStyle.left }"></div>
        <div class="text">
          <p>{{ item.name }}</p>
        </div>

      </div>
      <div ref=" moveDom" id="moveDom"></div>


    </section>

    <p   class="p-diff">差别【不准确】: {{ differencePercentage }}%</p>
  </div>
</template>

<script lang="ts" setup>
  
import imageYT from '../assets/yt.png';
import imageFX from '../assets/fx.png';
import pixelmatch from 'pixelmatch';

import { reactive, ref, onMounted, onBeforeUnmount } from 'vue';
  
 
 
let differencePercentage = ref(0);
onMounted(() => {
  compareImages();
});
function compareImages() {
  const imgA = document.createElement('img');
  const imgB = document.createElement('img');

  imgA.onload = () => {
    imgB.onload = () => {
      const width = imgA.width;
      const height = imgA.height;
      const canvasA = document.createElement('canvas');
      const canvasB = document.createElement('canvas');
      canvasA.width = width;
      canvasA.height = height;
      canvasB.width = width;
      canvasB.height = height;
      const ctxA = canvasA.getContext('2d') as any;
      const ctxB = canvasB.getContext('2d') as any;
      ctxA.drawImage(imgA, 0, 0);
      ctxB.drawImage(imgB, 0, 0);
      const dataA = ctxA.getImageData(0, 0, width, height);
      const dataB = ctxB.getImageData(0, 0, width, height);
      const diff = pixelmatch(dataA.data, dataB.data, null, width, height);
      differencePercentage.value =
        100 - parseInt(((diff / (width * height)) * 100).toFixed(2));
    };
    imgB.src = imageFX as any;
  };
  imgA.src = imageYT as any;
}

let imgData = reactive({
  imgDataVal: [
    {
      id: 1,
      name: '原始图',
      src: imageYT
    },
    {
      id: 2,
      name: '分析图',
      src: imageFX
    }
  ]
})

/**
 * @description: 添加鼠标事件
 * @return {*}
 */

const init = () => {
  moveDom.value = document.getElementById('moveDom')
  moveDom.value.addEventListener('mousemove', moveEvent)
  moveDom.value.addEventListener('wheel', wheelEvent)
  moveDom.value.addEventListener('mousedown', mousedownEvent)
  moveDom.value.addEventListener('mouseup', mouseupEvent)
  moveDom.value.addEventListener('mouseout', mouseoutEvent)
  moveDom.value.addEventListener('mouseover', mouseoverEvent)
}
onMounted(() => {

  init()
})


 const moveDom: any = ref(null);
const images: any = ref(null);
images.value = document.getElementsByClassName('chatImgs');
/**
 * @description: 卸载鼠标事件
 * @return {*}
 */
onBeforeUnmount(() => {
  moveDom.value.removeEventListener('mousemove', moveEvent);
  moveDom.value.removeEventListener('mouseleave', wheelEvent);
  moveDom.value.removeEventListener('mousedown', mousedownEvent);
});
const boxStyle = ref({
  width: 50,
  top: '50%',
  left: '50%',
});
const selectRegionStyle = ref({
  top: '50%',
  left: '50%',
});
const moveX = ref(null);
const moveY = ref(null);

/**
 * @description: 鼠标移动事件
 * @param {*} e
 * @return {*}
 */
const moveEvent = (e: any) => {
  moveX.value = e.offsetX;
  moveY.value = e.offsetY;
  selectRegionStyle.value.left = `${e.offsetX}px`;
  selectRegionStyle.value.top = `${e.offsetY}px`;
  if (clickState.value) {
    boxStyle.value.top = `${e.offsetY}px`;
    boxStyle.value.left = `${e.offsetX}px`;
  }
};
/**
 * @description: 滚轮事件
 * @param {*} e
 * @return {*}
 */
const wheelEvent = (e: any) => {
  if (e.deltaY < 0) {
    if (boxStyle.value.width > 200) {
      return;
    }
    boxStyle.value.width = boxStyle.value.width + 10;
  } else {
    if (boxStyle.value.width < 50) {
      return;
    }
    boxStyle.value.width = boxStyle.value.width - 10;
  }
};

const clickState = ref(false);
const overState = ref(false);
/**
 * @description: 鼠标左键按下事件
 * @param {*} e
 * @return {*}
 */
const mousedownEvent = (e: any) => {
  clickState.value = true;
  overState.value = true;
};
/**
 * @description: 鼠标移入事件
 * @param {*} e
 * @return {*}
 */
const mouseoverEvent = (e: any) => {
  if (overState.value) {
    clickState.value = true;
  }
};
/**
 * @description: 鼠标左键抬起事件
 * @param {*} e
 * @return {*}
 */
const mouseupEvent = (e: any) => {
  clickState.value = false;
  overState.value = false;
};
/**
 * @description: 鼠标移出事件
 * @param {*} e
 * @return {*}
 */
const mouseoutEvent = (e: any) => {
  clickState.value = false;
};
</script>

<style scoped lang="scss">
.box_container {
  width: 100vw;
  height: 100vh;

  padding: 0;

}


section {
  width: 100%;
  height: 85%;
  display: flex;
  justify-content: center;
  justify-items: center;


  >div {
    flex: 1;
    height: 100%;
    position: relative;
    overflow: hidden;
    background-color: #0decb8da;
    box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.07);

    img {
      width: 100%;
      position: absolute;
      transform: translate(-50%, -50%);
      z-index: 0;

    }

    .selectRegion {
      position: absolute;
      width: 100px;
      height: 100px;
      transform: translate(-50%, -50%);
      border: 1px solid rgba(0, 0, 0, 0.3);

    }
  }

  // 左边区域可以拖动
  #moveDom {
    width: 49.8%;
    height: 85.0%;
    background-color: rgba(0, 0, 0, 0);
    position: absolute;
    top: 0;
    left: 0;
    cursor: move;
  }

  >div:nth-child(1) {
    margin-right: 5px;
  }

  >div:nth-child(2) {
    cursor: no-drop;
    margin-left: 5px;
  }

  .text {
    width: 100%;
    height: 50px;
    position: absolute;
    bottom: 0;
    left: 0;
    background-color: rgba(0, 0, 0, 0.1);

    p {
      width: 100%;
      height: 100%;
      line-height: 100%;
      text-align: center;
      line-height: 50px;
      // color: #333;
      color: #fff;
      font-weight: 600;
      letter-spacing: 10px;
      font-size: 18px;
    }
  }
}
.p-diff{
  display: flex;
  justify-content: center;
  margin-top: 20px;
  font-size: 20px;
  font-weight:600
}
</style>
相关推荐
问道飞鱼1 分钟前
【前端知识】SCSS(Sassy CSS)是一种CSS预处理器语言
前端·css·less·scss
snow@li18 分钟前
vue3 + ts:开发插件 / Plugins / 注册全局实例 / 在 template 与 setup 中使用 / provide、inject
前端·javascript·vue.js
命运之光34 分钟前
【经典】高级动态抽奖系统(HTML,CSS、JS)
前端·css·html
დ旧言~43 分钟前
实战项目 Boost 搜索引擎
服务器·c语言·前端·网络·汇编·c++
森屿Serien1 小时前
Javaweb关于web.xml的相关配置信息
xml·前端
2301_801074151 小时前
初始ArkUI
javascript·css·html5·arkts
夏天想2 小时前
前端安全和解决方案
前端·安全
生椰拿铁You2 小时前
11 —— 打包模式的应用
前端
Want5952 小时前
HTML飞舞的爱心
前端·html
Hong.19482 小时前
vue本地调试设置虚拟域名
前端·javascript·vue.js