携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第14天,点击查看活动详情
本篇文章就不做介绍了,本文的二次开发主要是增加几种工具(椭圆选框工具,和自定义选框工具)和修改选框旁边的显示信息。
Cornerstone介绍可以参考我的另两篇文章
Cornerstone.js之Cornerstone在Vue中的应用
增加工具
一、先增加工具的标签
在原先的地方修改方法
二、增加和修改方法
增加的方法,cornerstoneToolsSelect,用于切换工具
修改的方法,addTools,增加要激活的工具
三、效果显示
修改显示信息
增加要修改的名字和颜色标签
需要单独引入cornerstoneTools文件夹源码
定义参数
将修改的参数赋值给公共参数
新增公共参数和修改配置
src/utils/commonality.js
修改cornerstone配置文件
引入公共参数
找到 _doneChangingTextCallback 方法
注释
另外两个选框工具同理
完整的效果图
完整代码
Test.vue
<template>
<div class="wrapper" v-loading="loading">
<el-row class="Container">
<!--菜单栏--图片列表-->
<el-col :span="4">
<div class="menuBar">
<li
@click="choose(index, item)"
:class="{ clickClass: activeIndex === index }"
v-for="(item, index) in group"
:key="index"
>
<!-- 已标注 -->
<img
v-if="item.state === 'complete'"
:src="completeMark"
/>
<!-- 未标注 -->
<img
v-else-if="item.state === 'wait'"
:src="waitMark"
/>
<span>{{ item.dataName }}</span>
</li>
</div>
</el-col>
<!-- 标注区域-->
<el-col :span="14">
<div class="mainBar">
<div class="toolBar">
<div class="tool">
<img
:src="rectangleRoiImg"
alt="标注笔"
title="标注笔"
@click="cornerstoneToolsSelect('RectangleRoi')"
/>
</div>
<div class="tool">
<img
:src="ellipseImg"
alt="椭圆"
title="椭圆"
@click="cornerstoneToolsSelect('EllipticalRoi')"
/>
</div>
<div class="tool">
<img
:src="customImg"
alt="自定义"
title="自定义"
@click="cornerstoneToolsSelect('FreehandRoi')"
/>
</div>
<div class="tool">
<img
:src="eraserImg"
alt="橡皮擦"
title="橡皮擦"
@click="cornerstoneToolsSelect('Eraser')"
/>
</div>
</div>
<div style="width: 100%">
<div id="test" class="imgContainer"></div>
</div>
</div>
</el-col>
<!-- 属性按钮栏-->
<el-col :span="6">
<div class="buttonContainer">
<div>
<!-- 选择类型 -->
<el-row class="header2"> 数据标注特征组合名称: </el-row>
<el-row>
<el-radio-group v-model="defectRadio">
<el-radio
v-for="item in defectTypeList"
class="radioItem"
:key="item.name"
:label="item.name"
@change="changeColor(item)"
>
<div
class="radioBlock"
:style="{ background: item.color }"
></div>
{{ item.name }}
</el-radio>
</el-radio-group>
</el-row>
</div>
</div>
</el-col>
</el-row>
</div>
</template>
<script>
// 渲染我们的图像,并提供有用的事件和方法来使响应视口变化的工具成为可能
import cornerstone from "cornerstone-core"
// 某些工具用于辅助向量数学或其他复杂运算的依赖项
import cornerstoneMath from "cornerstone-math"
// import cornerstoneTools from "cornerstone-tools"
import cornerstoneTools from "@/cornerstoneTools"
// 触摸事件和手势的跨浏览器支持
import Hammer from "hammerjs"
// web图片加载
import cornerstoneWebImageLoader from "cornerstone-web-image-loader"
cornerstoneTools.external.cornerstone = cornerstone
cornerstoneTools.external.Hammer = Hammer
cornerstoneTools.external.cornerstoneMath = cornerstoneMath
cornerstoneWebImageLoader.external.cornerstone = cornerstone
import $common from "@/utils/commonality.js"
export default {
name: "editAnnotation",
data() {
return {
cornerstoneToolsType: "RectangleRoi",
loading: false,
// 已标注
completeMark: require("../../assets/image/dataAnnotation/yiwancheng.png"),
// 未标注
waitMark: require("../../assets/image/dataAnnotation/daishenhe.png"),
// 标注笔
rectangleRoiImg: require("../../assets/image/dataAnnotation/pencil.png"),
// 橡皮擦
eraserImg: require("../../assets/image/dataAnnotation/eraser.png"),
//椭圆
ellipseImg: require("../../assets/image/dataAnnotation/ellipse.png"),
// 自定义
customImg: require("../../assets/image/dataAnnotation/custom.png"),
// 左侧菜单
activeIndex: -1,
group: [],
// 中间图片标注
imgSrc: "",
ele: null,
toolDatas: null,
defectRadio: "绿色",
defectTypeList: [
{
name: "绿色",
color: "green"
},
{
name: "红色",
color: "red"
},
{
name: "蓝色",
color: "blue"
}
],
markeData: {},
markeImgName: "",
markImgId: ""
}
},
computed: {},
created() {},
mounted() {
console.log("初始化")
this.$nextTick(() => {
$common.labelText = "绿色"
$common.labelColor = "green"
let group = [
{
id: "3587",
dataIo: "https://img-blog.csdnimg.cn/f05140deecf5426a8348600b04a1511b.png",
dataName: "wait-f15d275d82508c72b0d6eec84f11f0f.jpg",
state: "wait"
},
{
id: "3588",
dataIo: "https://img-blog.csdnimg.cn/52d607e5ca44450491eae93fdf8916ad.png",
dataName: "complete-dd17ee5124dcb64154f82e8d0fe4755.png",
state: "complete"
}
]
this.imgSrc =
"https://img-blog.csdnimg.cn/f05140deecf5426a8348600b04a1511b.png"
this.group = group
this.activeIndex = 0
this.initCornerstoneTools()
this.loadToolStates()
})
},
methods: {
//激活标注工具
cornerstoneToolsSelect(type) {
this.cornerstoneToolsType = type
this.activeTool(this.cornerstoneToolsType)
},
// 选择多张标注图片
choose(index, item) {
if (this.activeIndex === index) return
this.saveToolData()
this.activeIndex = index
//切换图片不会自动保存
// this.markeData = {}
this.activeIndex = index
this.markImgId = item.id
this.markeImgName = item.dataName
this.imgSrc = item.dataIo
this.clearToolState()
this.loadToolStates()
this.loadWebImg(this.imgSrc)
},
// 组合名称改变
changeColor(item) {
$common.labelText = item.name
$common.labelColor = item.color
},
// 初始化标注工具
initCornerstoneTools() {
cornerstoneTools.init({
showSVGCursors: true
})
// 获取元素标签
this.ele = document.querySelector("#test")
cornerstone.enable(this.ele)
// 加载图像
this.loadWebImg(this.imgSrc)
// 添加方形选框工具
this.addTools()
this.activeTool(this.cornerstoneToolsType)
// 添加选框颜色
cornerstoneTools.toolColors.setToolColor("green")
},
// 加载图像
loadWebImg(url) {
console.log("图片正在加载中")
cornerstone.loadAndCacheImage(url).then(image => {
cornerstone.displayImage(this.ele, image)
})
},
// 添加选框工具
addTools() {
// 添加工具
console.log("工具正在加载中")
// 方形选框
cornerstoneTools.addTool(
cornerstoneTools.RectangleRoiTool,
this.ele
)
// 椭圆选框
cornerstoneTools.addTool(
cornerstoneTools.EllipticalRoiTool,
this.ele
)
// 自定义选框
cornerstoneTools.addTool(cornerstoneTools.FreehandRoiTool, this.ele)
// 橡皮擦
cornerstoneTools.addTool(cornerstoneTools.EraserTool, this.ele)
},
// 激活工具
activeTool(toolName) {
// { mouseButtonMask: 1 } //鼠标左键点击触发
// { mouseButtonMask: 2 } //鼠标右键点击触发
// { mouseButtonMask: 4 } //鼠标滚轮键点击触发
// 启用工具
cornerstoneTools.setToolActive(toolName, { mouseButtonMask: 1 })
},
// 清除工具
clearToolState() {
if (!this.ele) return
cornerstoneTools.clearToolState(this.ele, "RectangleRoi")
// cornerstoneTools.clearToolState(this.ele, "EllipticalRoi")
// cornerstoneTools.clearToolState(this.ele, "FreehandRoi")
// cornerstoneTools.clearToolState(this.ele, "Eraser")
// cornerstoneTools.clearToolState(this.ele, this.cornerstoneToolsType)
cornerstone.updateImage(this.ele)
},
// 保存工具状态
saveToolData() {
let data = cornerstoneTools.getToolState(
this.ele,
this.cornerstoneToolsType
)
? JSON.parse(
JSON.stringify(
cornerstoneTools.getToolState(
this.ele,
this.cornerstoneToolsType
).data
)
)
: null
if (!data) return
this.markeData[this.group[this.activeIndex].id] = data
},
// 加载工具状态
loadToolStates() {
const toolDatas = this.markeData[this.group[this.activeIndex].id]
// const toolDatas = this.markeData[[this.markeImgName]]
if (!toolDatas) return
setTimeout(() => {
toolDatas.forEach(data => {
cornerstoneTools.addToolState(
this.ele,
this.cornerstoneToolsType,
data
)
})
cornerstone.updateImage(this.ele)
}, 300)
}
},
beforeDestroy() {
this.clearToolState()
}
}
</script>
<style lang="scss" scoped>
.wrapper {
text-align: left;
.header {
font-size: 24px;
font-weight: bold;
margin-bottom: 10px;
}
.header2 {
font-size: 18px;
font-weight: bold;
margin-top: 5px;
}
.Container {
border-top: 1px solid #b8cee0;
padding-top: 15px;
}
.menuBar {
height: 90vh;
border: solid 1px grey;
margin-left: 10px;
overflow: auto;
width: 100%;
li {
cursor: pointer;
list-style: none;
height: 50px;
white-space: nowrap;
padding-left: 10px;
display: flex;
justify-content: flex-start;
align-items: center;
min-width: max-content;
img {
width: 34px;
}
span {
margin-left: 10px;
}
}
//li选中颜色
.clickClass {
background: darken(#a7a7a7, 5%);
width: 100%;
}
//滚动条
&::-webkit-scrollbar {
height: 15px;
width: 15px;
}
&::-webkit-scrollbar-thumb {
border-radius: 10px;
box-shadow: inset 0 0 10px rgba(140, 140, 140, 0.8);
}
}
.mainBar {
margin: 0 16px;
display: flex;
flex-direction: row;
.toolBar {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
width: 40px;
background: #e8ebee;
.tool {
width: 30px;
margin: 0 5px;
height: 36px;
display: flex;
justify-content: center;
align-items: center;
border-bottom: 1px solid #7a90ab;
img {
cursor: pointer;
width: 22px;
}
}
}
.imgContainer {
height: 90vh;
border: 1px solid blue;
//margin: 0 16px;
}
}
.buttonContainer {
height: 70vh;
//border: 1px solid $menu-blue-color;
display: flex;
flex-direction: column;
justify-content: space-between;
.radioItem {
display: flex;
justify-content: flex-start;
align-items: center;
height: 24px;
line-height: 24px;
.radioBlock {
display: inline-block;
width: 12px;
height: 12px;
border-radius: 50%;
}
}
.checkItem {
display: block;
height: 24px;
line-height: 24px;
}
.buttonBar {
.el-row + .el-row {
margin-top: 10px;
}
}
}
}
</style>
我的源码地址及其他文件
链接:pan.baidu.com/s/1DH_iiMQF… 提取码:2vnt