fix: 🐛 Limit image download size to avoid browser issues (#1112)
* fix: 🐛 Limit image download size to avoid browser issues This fix adjusts the max texture size to allow browser compatibility (blob size limit) Closes: #1099 * CR Updates: Clamp values using math.min, remove unnecessary onBlur event and small adjustments
This commit is contained in:
parent
a3028ad1f6
commit
5716b71d40
@ -32,6 +32,7 @@ const DownloadDialog = ({
|
|||||||
downloadBlob,
|
downloadBlob,
|
||||||
defaultSize,
|
defaultSize,
|
||||||
minimumSize,
|
minimumSize,
|
||||||
|
maximumSize,
|
||||||
canvasClass,
|
canvasClass,
|
||||||
}) => {
|
}) => {
|
||||||
const [filename, setFilename] = useState(DEFAULT_FILENAME);
|
const [filename, setFilename] = useState(DEFAULT_FILENAME);
|
||||||
@ -75,24 +76,24 @@ const DownloadDialog = ({
|
|||||||
}, [defaultSize, disableViewport, enableViewport, viewportElement]);
|
}, [defaultSize, disableViewport, enableViewport, viewportElement]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
const validSize = value => (value >= minimumSize ? value : minimumSize);
|
||||||
const loadAndUpdateViewports = async () => {
|
const loadAndUpdateViewports = async () => {
|
||||||
const {
|
const {
|
||||||
image,
|
image,
|
||||||
width: scaledWidth,
|
width: scaledWidth,
|
||||||
height: scaledHeight,
|
height: scaledHeight,
|
||||||
} = await loadImage(activeViewport, viewportElement, width, height);
|
} = await loadImage(activeViewport, viewportElement, width, height);
|
||||||
|
|
||||||
setLastImage(image);
|
setLastImage(image);
|
||||||
|
|
||||||
toggleAnnotations(showAnnotations, viewportElement);
|
toggleAnnotations(showAnnotations, viewportElement);
|
||||||
|
|
||||||
setViewportElementHeight(scaledHeight);
|
setViewportElementHeight(validSize(scaledHeight));
|
||||||
setViewportElementWidth(scaledWidth);
|
setViewportElementWidth(validSize(scaledWidth));
|
||||||
|
|
||||||
setDownloadCanvas(state => ({
|
setDownloadCanvas(state => ({
|
||||||
...state,
|
...state,
|
||||||
height: scaledHeight,
|
height: validSize(scaledHeight),
|
||||||
width: scaledWidth,
|
width: validSize(scaledWidth),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -108,8 +109,8 @@ const DownloadDialog = ({
|
|||||||
setViewportPreview(state => ({
|
setViewportPreview(state => ({
|
||||||
...state,
|
...state,
|
||||||
src: dataUrl,
|
src: dataUrl,
|
||||||
width: viewportElementWidth,
|
width: validSize(viewportElementWidth),
|
||||||
height: viewportElementHeight,
|
height: validSize(viewportElementHeight),
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -125,10 +126,12 @@ const DownloadDialog = ({
|
|||||||
updateViewportPreview,
|
updateViewportPreview,
|
||||||
fileType,
|
fileType,
|
||||||
downloadCanvas.ref,
|
downloadCanvas.ref,
|
||||||
|
minimumSize,
|
||||||
|
maximumSize,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const onHeightChange = () => {
|
const onHeightChange = event => {
|
||||||
const newHeight = event.target.value;
|
const newHeight = Math.min(event.target.value, maximumSize);
|
||||||
setHeight(newHeight);
|
setHeight(newHeight);
|
||||||
|
|
||||||
setViewportElementHeight(newHeight);
|
setViewportElementHeight(newHeight);
|
||||||
@ -153,7 +156,7 @@ const DownloadDialog = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onWidthChange = event => {
|
const onWidthChange = event => {
|
||||||
const newWidth = event.target.value;
|
const newWidth = Math.min(event.target.value, maximumSize);
|
||||||
setWidth(newWidth);
|
setWidth(newWidth);
|
||||||
|
|
||||||
setViewportElementWidth(newWidth);
|
setViewportElementWidth(newWidth);
|
||||||
@ -212,6 +215,7 @@ const DownloadDialog = ({
|
|||||||
<TextInput
|
<TextInput
|
||||||
type="number"
|
type="number"
|
||||||
min={minimumSize}
|
min={minimumSize}
|
||||||
|
max={maximumSize}
|
||||||
value={width}
|
value={width}
|
||||||
label={t('Image width (px)')}
|
label={t('Image width (px)')}
|
||||||
onChange={onWidthChange}
|
onChange={onWidthChange}
|
||||||
@ -221,6 +225,7 @@ const DownloadDialog = ({
|
|||||||
<TextInput
|
<TextInput
|
||||||
type="number"
|
type="number"
|
||||||
min={minimumSize}
|
min={minimumSize}
|
||||||
|
max={maximumSize}
|
||||||
value={height}
|
value={height}
|
||||||
label={t('Image height (px)')}
|
label={t('Image height (px)')}
|
||||||
onChange={onHeightChange}
|
onChange={onHeightChange}
|
||||||
@ -329,6 +334,7 @@ DownloadDialog.propTypes = {
|
|||||||
downloadBlob: PropTypes.func.isRequired,
|
downloadBlob: PropTypes.func.isRequired,
|
||||||
defaultSize: PropTypes.number.isRequired,
|
defaultSize: PropTypes.number.isRequired,
|
||||||
minimumSize: PropTypes.number.isRequired,
|
minimumSize: PropTypes.number.isRequired,
|
||||||
|
maximumSize: PropTypes.number.isRequired,
|
||||||
canvasClass: PropTypes.string.isRequired,
|
canvasClass: PropTypes.string.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import cornerstoneTools from 'cornerstone-tools';
|
|||||||
|
|
||||||
const MINIMUM_SIZE = 100;
|
const MINIMUM_SIZE = 100;
|
||||||
const DEFAULT_SIZE = 512;
|
const DEFAULT_SIZE = 512;
|
||||||
|
const MAX_TEXTURE_SIZE = 10000;
|
||||||
|
|
||||||
const mapStateToProps = (state, ownProps) => {
|
const mapStateToProps = (state, ownProps) => {
|
||||||
const { viewportSpecificData, activeViewportIndex } = state.viewports;
|
const { viewportSpecificData, activeViewportIndex } = state.viewports;
|
||||||
@ -14,6 +15,7 @@ const mapStateToProps = (state, ownProps) => {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
minimumSize: MINIMUM_SIZE,
|
minimumSize: MINIMUM_SIZE,
|
||||||
|
maximumSize: MAX_TEXTURE_SIZE,
|
||||||
defaultSize: DEFAULT_SIZE,
|
defaultSize: DEFAULT_SIZE,
|
||||||
canvasClass: 'cornerstone-canvas',
|
canvasClass: 'cornerstone-canvas',
|
||||||
onClose: ownProps.toggleDownloadDialog,
|
onClose: ownProps.toggleDownloadDialog,
|
||||||
@ -74,7 +76,6 @@ const mapStateToProps = (state, ownProps) => {
|
|||||||
cornerstone.setViewport(viewportElement, viewport);
|
cornerstone.setViewport(viewportElement, viewport);
|
||||||
cornerstone.resize(viewportElement, true);
|
cornerstone.resize(viewportElement, true);
|
||||||
|
|
||||||
const MAX_TEXTURE_SIZE = 16384;
|
|
||||||
const newWidth = Math.min(width || image.width, MAX_TEXTURE_SIZE);
|
const newWidth = Math.min(width || image.width, MAX_TEXTURE_SIZE);
|
||||||
const newHeight = Math.min(
|
const newHeight = Math.min(
|
||||||
height || image.height,
|
height || image.height,
|
||||||
@ -108,7 +109,15 @@ const mapStateToProps = (state, ownProps) => {
|
|||||||
return window.navigator.msSaveBlob(blob, file);
|
return window.navigator.msSaveBlob(blob, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
return cornerstoneTools.SaveAs(viewportElement, file, mimetype);
|
viewportElement.querySelector('canvas').toBlob(blob => {
|
||||||
|
const URLObj = window.URL || window.webkitURL;
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = URLObj.createObjectURL(blob);
|
||||||
|
a.download = file;
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
document.body.removeChild(a);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user