-
Notifications
You must be signed in to change notification settings - Fork 597
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: displaying images (series) with different sizes causes the image (…
…#462) (#465) * fix: displaying images (series) with different sizes causes the image… (#462) * fix: displaying images (series) with different sizes causes the image to be clipped #304 * add example to display multiple images with different sizes * fix createViewport test Co-authored-by: swederik <erik.sweed@gmail.com>
- Loading branch information
1 parent
95516bf
commit c993fdb
Showing
25 changed files
with
439 additions
and
163 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
<!DOCTYPE HTML> | ||
<html> | ||
<head> | ||
<!-- twitter bootstrap CSS stylesheet - included to make things pretty, not needed or used by cornerstone --> | ||
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet"> | ||
</head> | ||
<body> | ||
<div class="container"> | ||
|
||
<h1> | ||
displayDifferentSizes/index.html | ||
</h1> | ||
|
||
This is an example of changing the image displayed in an element with different sizes | ||
and the option to set a displayedArea in the viewport. This is used to show how to reset | ||
the displayedArea on the viewport when the stack images are of different size. Use the mouse wheel | ||
to change between images or press the buttons below. | ||
<br> | ||
<br> | ||
<input type="checkbox" id="ApplyDisplayedArea"/> | ||
<label for="ApplyDisplayedArea">Apply Displayed Area</label> | ||
<button id="imageButton1" type="button" class="btn btn-default">Image #1</button> | ||
<button id="imageButton2" type="button" class="btn btn-default">Image #2</button> | ||
<button id="imageButton3" type="button" class="btn btn-default">Image #3</button> | ||
<br> | ||
<span><b>Image Size:</b></span><span id="imgSize"></span><span> | </span> | ||
<span><b>Displayed Area:</b></span><span id="displayedAreaSize"></span> | ||
<br> | ||
<div id="dicomImage" style="width:512px;height:512px" | ||
oncontextmenu="return false" | ||
onmousedown="return false"> | ||
</div> | ||
</div> | ||
</body> | ||
|
||
<!-- include the cornerstone library --> | ||
<script src="../../dist/cornerstone.js"></script> | ||
<script>window.cornerstone || document.write('<script src="https://unpkg.com/cornerstone-core">\x3C/script>')</script> | ||
<script src="../exampleImageIdLoaderRaw.js"></script> | ||
|
||
<script> | ||
const element = document.getElementById('dicomImage'); | ||
cornerstone.enable(element); | ||
|
||
const imageIds = [ | ||
'example://test1', | ||
'example://test2', | ||
'example://test3' | ||
]; | ||
|
||
let currentImageIndex = 0; | ||
element.addEventListener('cornerstonenewimage', (eventData) => { | ||
cornerstone.fitToWindow(eventData.detail.element); | ||
}); | ||
|
||
// show image #1 initially | ||
function updateTheImage(imageIndex) { | ||
currentImageIndex = imageIndex; | ||
cornerstone.loadImage(imageIds[currentImageIndex]).then(function(image) { | ||
const viewport = cornerstone.getViewport(element) || {}; | ||
const applyDisplayedArea = document.getElementById("ApplyDisplayedArea"); | ||
const imgSize = document.getElementById("imgSize"); | ||
const displayedAreaSize = document.getElementById("displayedAreaSize"); | ||
|
||
imgSize.textContent = image.width + "x" + image.height; | ||
|
||
viewport.voi = viewport.voi || {}; | ||
viewport.voi.windowWidth = image.windowWidth; | ||
viewport.voi.windowCenter = image.windowCenter; | ||
|
||
if (applyDisplayedArea.checked){ | ||
if (!viewport.displayedArea) { | ||
viewport.displayedArea = { | ||
// Top Left Hand Corner | ||
tlhc: { | ||
x: 1, | ||
y: 1 | ||
}, | ||
// Bottom Right Hand Corner | ||
brhc: { | ||
x: 256, | ||
y: 256 | ||
}, | ||
rowPixelSpacing: 1, | ||
columnPixelSpacing: 1, | ||
//presentationSizeMode: 'SCALE TO FIT' | ||
presentationSizeMode: 'None' | ||
}; | ||
|
||
displayedAreaSize.textContent = viewport.displayedArea.brhc.x + "x" + viewport.displayedArea.brhc.y; | ||
} | ||
} else { | ||
viewport.displayedArea = undefined; | ||
displayedAreaSize.textContent = "none"; | ||
} | ||
|
||
cornerstone.displayImage(element, image, viewport); | ||
}); | ||
} | ||
|
||
updateTheImage(0); | ||
|
||
document.getElementById('ApplyDisplayedArea').addEventListener('change', function (e) { | ||
updateTheImage(currentImageIndex); | ||
}); | ||
|
||
// Add event handlers to change images | ||
document.getElementById('imageButton1').addEventListener('click', function (e) { | ||
updateTheImage(0); | ||
}); | ||
|
||
document.getElementById('imageButton2').addEventListener('click', function (e) { | ||
updateTheImage(1); | ||
}); | ||
|
||
document.getElementById('imageButton3').addEventListener('click', function (e) { | ||
updateTheImage(2); | ||
}); | ||
|
||
const wheelEvents = ['mousewheel', 'DOMMouseScroll']; | ||
|
||
wheelEvents.forEach((eventType) => { | ||
element.addEventListener(eventType, function (e) { | ||
// Firefox e.detail > 0 scroll back, < 0 scroll forward | ||
// chrome/safari e.wheelDelta < 0 scroll back, > 0 scroll forward | ||
if (e.wheelDelta < 0 || e.detail > 0) { | ||
if (currentImageIndex < imageIds.length - 1) { | ||
updateTheImage(++currentImageIndex); | ||
} | ||
} else { | ||
if (currentImageIndex > 0) { | ||
updateTheImage(--currentImageIndex); | ||
} | ||
} | ||
|
||
// Prevent page fom scrolling | ||
return false; | ||
}); | ||
}); | ||
</script> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"imageId": "example//test1", | ||
"minPixelValue": 0, | ||
"maxPixelValue": 2143, | ||
"slope": 1.0, | ||
"intercept": -1024, | ||
"windowCenter": 36, | ||
"windowWidth": 360, | ||
"rows": 512, | ||
"columns": 512, | ||
"height": 512, | ||
"width": 512, | ||
"color": false, | ||
"columnPixelSpacing": 0.8769, | ||
"rowPixelSpacing": 0.8769, | ||
"sizeInBytes": 524288 | ||
} |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"imageId": "example//test2", | ||
"minPixelValue": 0, | ||
"maxPixelValue": 1695, | ||
"slope": 1.0, | ||
"intercept": 0, | ||
"windowCenter": 844, | ||
"windowWidth": 2677, | ||
"rows": 256, | ||
"columns": 256, | ||
"height": 256, | ||
"width": 256, | ||
"color": false, | ||
"columnPixelSpacing": 0.234, | ||
"rowPixelSpacing": 0.234, | ||
"sizeInBytes": 131072 | ||
} |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"imageId": "example//test3", | ||
"minPixelValue": 15664, | ||
"maxPixelValue": 65535, | ||
"slope": 1.0, | ||
"intercept": 0, | ||
"windowCenter": 43079, | ||
"windowWidth": 12666, | ||
"rows": 1876, | ||
"columns": 1620, | ||
"height": 1876, | ||
"width": 1620, | ||
"color": false, | ||
"columnPixelSpacing": 0.15583, | ||
"rowPixelSpacing": 0.15583, | ||
"sizeInBytes": 6078240 | ||
} |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,71 +1,85 @@ | ||
(function (cs) { | ||
|
||
"use strict"; | ||
|
||
function getExampleImage(imageId) { | ||
let testCase = imageId.split('//')[1]; | ||
function getExampleImage (imageId) { | ||
const testCase = imageId.split('//')[1]; | ||
|
||
return { | ||
promise: new Promise((resolve) => { | ||
getImagePixel(testCase).then((imagePixel) => { | ||
getImageData(testCase).then((imageData) => { | ||
imageData.getPixelData = () => { return imagePixel; }; | ||
return { | ||
promise: new Promise((resolve) => { | ||
getImageData(testCase).then((imageData) => { | ||
getImagePixel(testCase, imageData).then((imagePixel) => { | ||
imageData.getPixelData = () => imagePixel; | ||
|
||
resolve(imageData); | ||
}); | ||
}); | ||
resolve(imageData); | ||
}); | ||
}); | ||
}), | ||
cancelFn: undefined | ||
}; | ||
|
||
}), | ||
cancelFn: undefined | ||
}; | ||
function getImagePixel (imageId, imageData) { | ||
const promise = new Promise((resolve) => { | ||
const req = new XMLHttpRequest(); | ||
|
||
req.onreadystatechange = function () { | ||
if (this.readyState === 4 && this.status === 200) { | ||
const imageRaw = req.responseText; | ||
const bpp = imageData.sizeInBytes / (imageData.width * imageData.height); | ||
|
||
if (bpp === 1) { | ||
const pixelData = Uint8Array.from(atob(imageRaw), (c) => c.charCodeAt(0)); | ||
|
||
function getImagePixel(imageId) { | ||
let promise = new Promise((resolve) => { | ||
var req = new XMLHttpRequest(); | ||
req.onreadystatechange = function () { | ||
if (this.readyState == 4 && this.status === 200 ) { | ||
let imageRaw = req.responseText; | ||
let pixelData = Uint8Array.from(atob(imageRaw), c => c.charCodeAt(0)); | ||
resolve(pixelData); | ||
} else if (bpp === 2) { | ||
const decodedData = atob(imageRaw); | ||
const pixelData = new Uint16Array(decodedData.length / 2); | ||
let count = 0; | ||
|
||
for (let i = 0; i < pixelData.length; i++) { | ||
pixelData[i] = decodedData.charCodeAt(count++) + (decodedData.charCodeAt(count++) << 8); | ||
|
||
resolve(pixelData); | ||
} | ||
|
||
resolve(pixelData); | ||
} | ||
req.open('GET', baseUrl + imageId + '.txt', true); | ||
req.send(); | ||
}); | ||
} | ||
}; | ||
req.open('GET', `${baseUrl + imageId}.txt`, true); | ||
req.send(); | ||
}); | ||
|
||
return promise; | ||
} | ||
|
||
return promise; | ||
} | ||
function getImageData (imageId) { | ||
const promise = new Promise((resolve) => { | ||
const req = new XMLHttpRequest(); | ||
|
||
function getImageData(imageId) { | ||
let promise = new Promise((resolve) => { | ||
var req = new XMLHttpRequest(); | ||
req.onreadystatechange = function () { | ||
if (this.readyState === 4 && this.status === 200) { | ||
let imageData = req.responseText; | ||
req.onreadystatechange = function () { | ||
if (this.readyState === 4 && this.status === 200) { | ||
const imageData = req.responseText; | ||
|
||
try { | ||
let image = JSON.parse(imageData); | ||
try { | ||
const image = JSON.parse(imageData); | ||
|
||
resolve(image); | ||
} | ||
catch (err) { | ||
console.error(err); | ||
} | ||
} | ||
resolve(image); | ||
} catch (err) { | ||
console.error(err); | ||
} | ||
req.open('GET', baseUrl + imageId + '.json', true); | ||
req.send(); | ||
}); | ||
} | ||
}; | ||
req.open('GET', `${baseUrl + imageId}.json`, true); | ||
req.send(); | ||
}); | ||
|
||
return promise; | ||
} | ||
return promise; | ||
} | ||
} | ||
|
||
|
||
|
||
var baseUrl = window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) + '/test-cases/'; | ||
var baseUrl = `${window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/'))}/test-cases/`; | ||
|
||
// register our imageLoader plugin with cornerstone | ||
cs.registerImageLoader('example', getExampleImage); | ||
// register our imageLoader plugin with cornerstone | ||
cs.registerImageLoader('example', getExampleImage); | ||
|
||
}(cornerstone)); | ||
})(cornerstone); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.