1、Django中写一个后端接口,给HTML提供dicom文件接口的方式
1、首先创建django项目
1、下载安装跨域的包
pip3 install django-cors-headers
2、使用pycharm创建一个Django项目
3、点击创建在另一个窗口,这个都无所谓,怎么都行,就是打开这个项目
4、创建成功的项目就是下面这个样子
5、先修改几个选项,后面好操作
下面是我的settings设置,我把修改的地方标注出来
"""
Django settings for pacsdemo project.Generated by 'django-admin startproject' using Django 3.2.18.For more information on this file, see
https://docs.djangoproject.com/en/3.2/topics/settings/For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.2/ref/settings/
"""
# 添加这个import os
import os
from pathlib import Path# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-uv!_mka##8#citwx_q$o71)@!8tfaa-6wyrb!h8&4fm+m-=-d='# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
# 设置所有IP都可以访问,局域网
ALLOWED_HOSTS = ['*']# Application definition# 添加跨域设置
INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','pacs.apps.PacsConfig','corsheaders' # 跨域设置
]MIDDLEWARE = ['django.middleware.security.SecurityMiddleware','django.contrib.sessions.middleware.SessionMiddleware','django.middleware.common.CommonMiddleware','django.middleware.csrf.CsrfViewMiddleware','django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware',
]# 新添加的设置
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_ALL_ORIGINS = False
CORS_ORIGIN_WHITELIST = ["http://192.168.0.30:8000","http://localhost:63409",
]
CORS_ORIGIN_ALLOW_ALL = TrueCORS_ALLOW_METHODS = ('DELETE','GET','OPTIONS','PATCH','POST','PUT','VIEW'
)CORS_ALLOW_HEADERS = ('accept','accept-encoding','authorization','content-type','dnt','origin','user-agent','x-csrftoken','x-requested-with',
)ROOT_URLCONF = 'pacsdemo.urls'TEMPLATES = [{'BACKEND': 'django.template.backends.django.DjangoTemplates','DIRS': [BASE_DIR / 'templates'],'APP_DIRS': True,'OPTIONS': {'context_processors': ['django.template.context_processors.debug','django.template.context_processors.request','django.contrib.auth.context_processors.auth','django.contrib.messages.context_processors.messages',],},},
]WSGI_APPLICATION = 'pacsdemo.wsgi.application'# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases# 连接本地的mysql数据库
DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','NAME': 'pacsdemo', # 你的数据库名称'USER': '******', # 你的账户'PASSWORD': '******', #你的密码'HOST': '127.0.0.1','PORT': '3306',}
}# Password validation
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validatorsAUTH_PASSWORD_VALIDATORS = [{'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',},{'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',},{'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',},{'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',},
]# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/# 设置时间,上海的时间
LANGUAGE_CODE = 'zh-Hans'TIME_ZONE = 'Asia/Shanghai'USE_I18N = TrueUSE_L10N = TrueUSE_TZ = False# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/# 加载静态文件的设置
STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static'),
]# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-fieldDEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
6、把表结构映射到数据库中
连接数据库的设置,没有这个设置,数据库会连接失败
import pymysql
pymysql.install_as_MySQLdb()
7、在终端运行两行命令
python manage.py makemigrations
8、运行第二行命令
python manage.py migrate
9、第一步完成,数据库连接成功,基础设置完成
2、写前端页面,并且和后端接口,传递单个dicom文件,并且显示出来
1、先添加一个路由
from django.conf.urls import include
2、然后在pacs中写urls.py里面的内容
from django.urls import pathfrom . import viewsurlpatterns = [path("index/", views.index), # 设置首页内容path("read/", views.read), # 读dicom文件path("read1/", views.read1), # 读dicom文件
]
3、写这个index的方法,在views.py中
from django.shortcuts import render
from django.http import HttpResponse, FileResponse# Create your views here.
def index(request):return render(request, 'index.html')def read(request):file = open('static/dicom/C9214289', 'rb')response = FileResponse(file)response['Content-Type'] = 'application/octet-stream'response['Content-Disposition'] = 'attachment;filename="1.dcm"'return responsedef read1(request):file = open('static/dicom/C9214530', 'rb')response = FileResponse(file)response['Content-Type'] = 'application/octet-stream'response['Content-Disposition'] = 'attachment;filename="2.dcm"'return response
4、写index.html的内容
我写的这个html,直接放进去就可以看,其中的内容你可以通过cornerstone.js查看
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>pacs</title><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script><script type="text/javascript">// 阻止右键点击事件的默认行为document.addEventListener('contextmenu', function (event) {event.preventDefault();});</script><script>// 监听双击事件,并阻止默认的缩放行为document.addEventListener('dblclick', function (event) {event.preventDefault();});document.addEventListener('touchstart', function (event) {if (event.touches.length > 1) {event.preventDefault();}}, {passive: false});</script>
</head>
<body>
<div><h2>全部都是鼠标左键的操作</h2><button id="wwwc">切换窗宽窗位</button><button id="length">切换测量长度</button><button id="rotate">旋转</button><button id="magnify">透视</button><button id="pan">移动</button><br/><button id="scaleoverlay">尺度</button><button id="zoom">放大</button><button id="angle">测量角度</button><button id="arrowannotate">添加备注</button><button id="bidirectional">交叉线</button><br/><button id="cobbangle">心胸比</button><button id="ellipticalroi">圆</button><button id="freehandroi">随便画</button><button id="probe">探针</button><button id="rectangleroi">方形</button><br/><button id="circlescissors">画圆</button><button id="rectanglescissors">画正方形</button>
</div>
<div id="dicomImage" style="width: 512px;height: 512px;position: absolute"></div></body>
<!-- 触控的方法 -->
<script src="https://unpkg.com/hammerjs@2.0.8/hammer.js"></script>
<!-- 基石包,核心包 -->
<script src="https://unpkg.com/cornerstone-core@2.6.1/dist/cornerstone.js"></script>
<!-- Math包,数学包 -->
<script src="https://unpkg.com/cornerstone-math@0.1.10/dist/cornerstoneMath.min.js"></script>
<!-- 图片解析包,解析dcm文件的 -->
<script src="https://unpkg.com/cornerstone-wado-image-loader@4.13.2/dist/cornerstoneWADOImageLoader.bundle.min.js"></script>
<!-- 解析普通图的方法 -->
<script src="https://unpkg.com/cornerstone-web-image-loader@2.1.1/dist/cornerstoneWebImageLoader.min.js"></script>
<!-- 写好方法的包 -->
<script src="https://unpkg.com/cornerstone-tools@6.0.10/dist/cornerstoneTools.js"></script>
<!-- 解析dicom的json信息 -->
<script src="https://unpkg.com/dicom-parser@1.8.21/dist/dicomParser.min.js"></script><script>cornerstoneTools.external.cornerstone = cornerstone;cornerstoneTools.external.cornerstoneMath = cornerstoneMath;cornerstoneTools.external.Hammer = Hammer;cornerstoneWADOImageLoader.external.dicomParser = dicomParser;cornerstoneWADOImageLoader.external.cornerstone = cornerstone;// 'dicomweb' 网页上的一种解析的包, http开头的网址 ,获取dicom的文件,并且显示出来var imageId = "wadouri:http://127.0.0.1:8000/read";var imageIds = ["wadouri:http://127.0.0.1:8000/read", "wadouri:http://127.0.0.1:8000/read1"]// 定义stack滚动工具const StackScrollMouseWheelTool = cornerstoneTools.StackScrollMouseWheelTool// Add our tool, and set it's modeconst StackScrollTool = cornerstoneTools.StackScrollTool//define the stack// 设置一个栈const stack = {currentImageIdIndex: 0,imageIds}// 默认初始化toolscornerstoneTools.init()// 获取页面显示的dicom idvar element = document.getElementById('dicomImage');cornerstone.enable(element)// 测量长度const LengthTool = cornerstoneTools.LengthTool;cornerstoneTools.addTool(LengthTool)// cornerstoneTools.setToolActive('Length', {mouseButtonMask: 1})// wwwcconst WwwcTool = cornerstoneTools.WwwcTool;cornerstoneTools.addTool(WwwcTool)// cornerstoneTools.setToolActive('Wwwc', {mouseButtonMask: 1})// 旋转const RotateTool = cornerstoneTools.RotateTool;cornerstoneTools.addTool(RotateTool)// 透视const MagnifyTool = cornerstoneTools.MagnifyTool;cornerstoneTools.addTool(MagnifyTool)// 移动const PanTool = cornerstoneTools.PanTool;cornerstoneTools.addTool(PanTool)// 尺度const ScaleOverlayTool = cornerstoneTools.ScaleOverlayTool;cornerstoneTools.addTool(ScaleOverlayTool)// 放大const ZoomTool = cornerstoneTools.ZoomTool;cornerstoneTools.addTool(cornerstoneTools.ZoomTool, {// Optional configurationconfiguration: {invert: false,preventZoomOutsideImage: false,minScale: .1,maxScale: 20.0,}});// 测量角度const AngleTool = cornerstoneTools.AngleTool;cornerstoneTools.addTool(AngleTool)// 添加备注const ArrowAnnotateTool = cornerstoneTools.ArrowAnnotateTool;cornerstoneTools.addTool(ArrowAnnotateTool)// 交叉线const BidirectionalTool = cornerstoneTools.BidirectionalTool;cornerstoneTools.addTool(BidirectionalTool)// 心胸比const CobbAngleTool = cornerstoneTools.CobbAngleTool;cornerstoneTools.addTool(CobbAngleTool)// 圆const EllipticalRoiTool = cornerstoneTools.EllipticalRoiTool;cornerstoneTools.addTool(EllipticalRoiTool)// 画笔const FreehandRoiTool = cornerstoneTools.FreehandRoiTool;cornerstoneTools.addTool(FreehandRoiTool)// 探针const ProbeTool = cornerstoneTools.ProbeTool;cornerstoneTools.addTool(ProbeTool)// 正方形长方形const RectangleRoiTool = cornerstoneTools.RectangleRoiTool;cornerstoneTools.addTool(RectangleRoiTool)// 直接画圆const CircleScissorsTool = cornerstoneTools.CircleScissorsTool;cornerstoneTools.addTool(CircleScissorsTool)// 通过正方形涂const RectangleScissorsTool = cornerstoneTools.RectangleScissorsTool;cornerstoneTools.addTool(RectangleScissorsTool)// 鼠标中键滚动cornerstone.loadAndCacheImage(imageIds[0]).then(function (image) {cornerstone.displayImage(element, image)cornerstoneTools.addStackStateManager(element, ['stack'])cornerstoneTools.addToolState(element, 'stack', stack)})cornerstoneTools.addTool(StackScrollMouseWheelTool)cornerstoneTools.setToolActive('StackScrollMouseWheel', {})function disableAllTools() {// 取消左键的功能cornerstoneTools.setToolDisabled('Length')cornerstoneTools.setToolDisabled('Wwwc')cornerstoneTools.setToolDisabled('Rotate')cornerstoneTools.setToolDisabled('Magnify')cornerstoneTools.setToolDisabled('ScaleOverlay')cornerstoneTools.setToolDisabled('Zoom')cornerstoneTools.setToolDisabled('Angle')cornerstoneTools.setToolDisabled('ArrowAnnotate')cornerstoneTools.setToolDisabled('Pan')cornerstoneTools.setToolDisabled('Bidirectional')cornerstoneTools.setToolDisabled('CobbAngle')cornerstoneTools.setToolDisabled('EllipticalRoi')cornerstoneTools.setToolDisabled('FreehandRoi')cornerstoneTools.setToolDisabled('Probe')cornerstoneTools.setToolDisabled('RectangleRoi')cornerstoneTools.setToolDisabled('CircleScissors')cornerstoneTools.setToolDisabled('RectangleScissors')}document.getElementById("wwwc").addEventListener('click', function () {// 取消左键原来的功能disableAllTools();// 激活窗宽窗位cornerstoneTools.setToolActive("Wwwc", {mouseButtonMask: 1})})document.getElementById("length").addEventListener('click', function () {// 取消左键原来的功能disableAllTools();// 激活测量长度cornerstoneTools.setToolActive("Length", {mouseButtonMask: 1})})document.getElementById("rotate").addEventListener('click', function () {// 取消左键原来的功能disableAllTools();// 激活旋转cornerstoneTools.setToolActive("Rotate", {mouseButtonMask: 1})})document.getElementById("magnify").addEventListener('click', function () {// 取消左键原来的功能disableAllTools();// 激活透视cornerstoneTools.setToolActive("Magnify", {mouseButtonMask: 1})})document.getElementById("pan").addEventListener('click', function () {// 取消左键原来的功能disableAllTools();// 激活 移动cornerstoneTools.setToolActive("Pan", {mouseButtonMask: 1})})document.getElementById("scaleoverlay").addEventListener('click', function () {// 取消左键原来的功能disableAllTools();// 激活 尺子cornerstoneTools.setToolActive("ScaleOverlay", {mouseButtonMask: 1})})document.getElementById("zoom").addEventListener('click', function () {// 取消左键原来的功能disableAllTools();// 激活 放大cornerstoneTools.setToolActive("Zoom", {mouseButtonMask: 1})})document.getElementById("angle").addEventListener('click', function () {// 取消左键原来的功能disableAllTools();// 激活 角度cornerstoneTools.setToolActive("Angle", {mouseButtonMask: 1})})document.getElementById("arrowannotate").addEventListener('click', function () {// 取消左键原来的功能disableAllTools();// 激活 添加备注cornerstoneTools.setToolActive("ArrowAnnotate", {mouseButtonMask: 1})})document.getElementById("bidirectional").addEventListener('click', function () {// 取消左键原来的功能disableAllTools();// 激活交叉线cornerstoneTools.setToolActive("Bidirectional", {mouseButtonMask: 1})})document.getElementById("cobbangle").addEventListener('click', function () {// 取消左键原来的功能disableAllTools();// 激活心胸比cornerstoneTools.setToolActive("CobbAngle", {mouseButtonMask: 1})})document.getElementById("ellipticalroi").addEventListener('click', function () {// 取消左键原来的功能disableAllTools();// 激活 圆cornerstoneTools.setToolActive("EllipticalRoi", {mouseButtonMask: 1})})document.getElementById("freehandroi").addEventListener('click', function () {// 取消左键原来的功能disableAllTools();// 激活 随便画cornerstoneTools.setToolActive("FreehandRoi", {mouseButtonMask: 1})})document.getElementById("probe").addEventListener('click', function () {// 取消左键原来的功能disableAllTools();// 激活 探针cornerstoneTools.setToolActive("Probe", {mouseButtonMask: 1})})document.getElementById("rectangleroi").addEventListener('click', function () {// 取消左键原来的功能disableAllTools();// 激活 方形cornerstoneTools.setToolActive("RectangleRoi", {mouseButtonMask: 1})})document.getElementById("circlescissors").addEventListener('click', function () {// 取消左键原来的功能disableAllTools();// 激活 方形cornerstoneTools.setToolActive("CircleScissors", {mouseButtonMask: 1})})document.getElementById("rectanglescissors").addEventListener('click', function () {// 取消左键原来的功能disableAllTools();// 激活 方形cornerstoneTools.setToolActive("RectangleScissors", {mouseButtonMask: 1})})</script></html>
5、启动项目
1、第一种,通过pycharm打开
2、第二种,命令行的方式
python manage.py runserver
5、查看网页
其中的功能都可以进行操作,后续我进行优化,默认滚动条是切换dicom
http://127.0.0.1:8000/index/