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:
Igor Octaviano 2019-10-29 17:36:34 -03:00 committed by Danny Brown
parent a3028ad1f6
commit 5716b71d40
2 changed files with 27 additions and 12 deletions

View File

@ -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,
}; };

View File

@ -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);
});
}, },
}; };
}; };