more improvements ot image annotatiotns
This commit is contained in:
@@ -125,7 +125,7 @@ button a {
|
||||
float: right;
|
||||
}
|
||||
|
||||
#dicom-element {
|
||||
#dicom-image {
|
||||
width: 60%;
|
||||
float: left;
|
||||
height: 600px;
|
||||
|
||||
@@ -36,6 +36,8 @@ $(document).ready(function () {
|
||||
|
||||
if($("#dicom-image").length) {
|
||||
|
||||
console.log("Dicom element found ", $("#dicom-image"));
|
||||
|
||||
$('#dicom-image').bind('contextmenu', function(e) {
|
||||
return false;
|
||||
});
|
||||
@@ -53,7 +55,7 @@ cornerstoneTools.init();
|
||||
const RotateTool = cornerstoneTools.RotateTool;
|
||||
const StackScrollTool = cornerstoneTools.StackScrollTool;
|
||||
const MagnifyTool = cornerstoneTools.MagnifyTool;
|
||||
|
||||
const ArrowAnnotateTool = cornerstoneTools.ArrowAnnotateTool;
|
||||
|
||||
|
||||
const element = document.getElementById('dicom-image');
|
||||
@@ -71,14 +73,40 @@ cornerstone.loadAndCacheImage(imageId).then(function(image) {
|
||||
cornerstoneTools.addTool(RotateTool);
|
||||
cornerstoneTools.addTool(StackScrollTool);
|
||||
cornerstoneTools.addTool(MagnifyTool);
|
||||
|
||||
cornerstoneTools.addTool(ArrowAnnotateTool, {
|
||||
configuration: {
|
||||
getTextCallback: () => {},
|
||||
changeTextCallback: () => {},
|
||||
allowEmptyLabel: true,
|
||||
renderDashed: false,
|
||||
drawHandles: false,
|
||||
drawHandlesOnHover: true,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Enable our tools
|
||||
// Avoid incorrect aspect ratio
|
||||
cornerstone.resize(element);
|
||||
cornerstoneTools.setToolActive("Pan", { mouseButtonMask: 1 });
|
||||
cornerstoneTools.setToolActive("Wwwc", { mouseButtonMask: 2 });
|
||||
cornerstoneTools.setToolActive("ZoomMouseWheel", { mouseButtonMask: 3 });
|
||||
cornerstoneTools.setToolActive("Zoom", { mouseButtonMask: 4 });
|
||||
|
||||
if (element.dataset.edit_annotation == "true") {
|
||||
cornerstoneTools.setToolActive("ArrowAnnotate", { mouseButtonMask: 2 });
|
||||
} else {
|
||||
cornerstoneTools.setToolEnabled("ArrowAnnotate");
|
||||
}
|
||||
|
||||
if (element.dataset.annotations) {
|
||||
loadJsonToolStateOnCurrentImage(element.dataset.annotations)
|
||||
}
|
||||
|
||||
cornerstone.resize(element);
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@@ -132,3 +160,44 @@ function prepAnswerData() {
|
||||
})
|
||||
$("#id_marked_answers").val(JSON.stringify(window.marked_answers));
|
||||
}
|
||||
|
||||
function getJsonToolStateNoId() {
|
||||
const el = document.getElementById("dicom-image");
|
||||
|
||||
const c = cornerstone.getEnabledElement(el);
|
||||
|
||||
const toolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager;
|
||||
|
||||
const image_id = c.image.imageId;
|
||||
|
||||
const state_with_id = toolStateManager.saveToolState()
|
||||
|
||||
const json_tool_state = JSON.stringify(state_with_id[image_id]);
|
||||
|
||||
return json_tool_state;
|
||||
|
||||
}
|
||||
|
||||
|
||||
function loadJsonToolStateOnCurrentImage(json) {
|
||||
let el = document.getElementById("dicom-image");
|
||||
|
||||
const toolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager;
|
||||
|
||||
const c = cornerstone.getEnabledElement(el);
|
||||
|
||||
let image_id = c.image.imageId;
|
||||
|
||||
let tool_state_no_id = JSON.parse(json);
|
||||
|
||||
let tool_state = {};
|
||||
tool_state[image_id] = tool_state_no_id;
|
||||
|
||||
toolStateManager.restoreToolState(tool_state);
|
||||
|
||||
cornerstone.reset(el);
|
||||
|
||||
return tool_state;
|
||||
|
||||
|
||||
}
|
||||
@@ -41,7 +41,7 @@
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div id="dicom-image" data-url="{{ question.image.url}}" />
|
||||
<div id="dicom-image" data-url="{{ question.image.url}}" data-annotations='{{question.image_annotations}}'>
|
||||
</div>
|
||||
|
||||
<form method="POST" class="post-form">{% csrf_token %}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<h2>Marking question {{question_details.current}} of {{question_details.total}}</h2>
|
||||
<p>{{ question.question_type }}</p>
|
||||
|
||||
<div id="dicom-image" data-url="{{ question.image.url}}" />
|
||||
<div id="dicom-image" data-url="{{ question.image.url}}" data-annotations='{{question.image_annotations}}'>
|
||||
</div>
|
||||
<div class="marking">
|
||||
<form method="POST" class="post-form">{% csrf_token %}
|
||||
|
||||
@@ -1,15 +1,56 @@
|
||||
{% extends 'anatomy/base.html' %}
|
||||
|
||||
{% block content %}
|
||||
<div id="dicom-image" data-url="{{ question.image.url}}" />
|
||||
{% load static %}
|
||||
<div id="dicom-image" data-url="{{ question.image.url}}" data-annotations='{{question.image_annotations}}' data-edit_annotation=true>
|
||||
<!-- testing -->
|
||||
<!--<div id="dicom-image" data-url="http://localhost:8000/static/abdoct.jpg"
|
||||
data-annotations='{{question.image_annotations}}' data-edit_annotation=true></div>-->
|
||||
<button id="save-annotations">Save Annotations</button>
|
||||
<div class="question">
|
||||
<div class="date">
|
||||
{{ question.created_date }}
|
||||
Created: {{ question.created_date }}
|
||||
</div>
|
||||
<h1>{{ question.GetPrimaryAnswer }}</h1>
|
||||
<h2>{{question.question_type}}</h2>
|
||||
Answers (score): {% for answer in question.answers.all %}
|
||||
{{ answer }} ({{answer.status}}),
|
||||
{% endfor %}
|
||||
<div>
|
||||
Examinations: {% for exam in question.exams.all %}
|
||||
{{ exam.name }}
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div>
|
||||
Annotation JSON: {{ question.image_annotations }}
|
||||
</div>
|
||||
<h1>{% for answer in question.answers.all %}
|
||||
{{ answer }},
|
||||
{% endfor %}</h1>
|
||||
<p>{{ question.question_type.first|linebreaksbr }}</p>
|
||||
<img src="/media/anatomy/{{ question.image|linebreaksbr }}" />
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
// send request to change the is_private state on customSwitches toggle
|
||||
$("#save-annotations").click(function () {
|
||||
json = getJsonToolStateNoId();
|
||||
$.ajax({
|
||||
url: "{% url 'anatomy:question_save_annotation' pk=question.pk %}",
|
||||
data: {
|
||||
csrfmiddlewaretoken: "{{ csrf_token }}",
|
||||
annotation: json,
|
||||
},
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
})
|
||||
// $.ajax().done(), $.ajax().fail(), $ajax().always() are upto you. Add/change accordingly
|
||||
.done(function (data) {
|
||||
console.log(data);
|
||||
// show some message according to the response.
|
||||
// For eg. A message box showing that the status has been changed
|
||||
})
|
||||
.always(function () {
|
||||
console.log('[Done]');
|
||||
})
|
||||
})
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -7,6 +7,7 @@ urlpatterns = [
|
||||
# path('', views.question_list, name='question_list'),
|
||||
path("", views.index, name="index"),
|
||||
path("question/<int:pk>/", views.question_detail, name="question_detail"),
|
||||
path("question/<int:pk>/save_annotation", views.question_save_annotation, name="question_save_annotation"),
|
||||
path("question/<int:pk>/answer/",
|
||||
views.answer_question,
|
||||
name="answer_question"),
|
||||
|
||||
@@ -474,6 +474,21 @@ def active_exams(request):
|
||||
return JsonResponse(active_exams)
|
||||
|
||||
|
||||
def question_save_annotation(request, pk):
|
||||
if request.is_ajax() and request.method=='POST':
|
||||
question = get_object_or_404(AnatomyQuestion, pk=pk)
|
||||
|
||||
question.image_annotations = request.POST.get("annotation")
|
||||
print(question.image_annotations)
|
||||
|
||||
question.save()
|
||||
data = {'status':'success'}
|
||||
return JsonResponse(data, status=200)
|
||||
else:
|
||||
data = {'status':'error'}
|
||||
return JsonResponse(data, status=400)
|
||||
|
||||
|
||||
def exam_json(request, pk):
|
||||
|
||||
exam = get_object_or_404(Exam, pk=pk)
|
||||
@@ -497,6 +512,7 @@ def exam_json(request, pk):
|
||||
"title": "{}".format(q.description),
|
||||
"question": str(q.question_type),
|
||||
"images": [image_as_base64(q.image)],
|
||||
"annotations": [q.image_annotations],
|
||||
"type": "anatomy",
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user