Skip to content

Commit

Permalink
[HCS images] Ability to download displayed TIFF file (#2527)
Browse files Browse the repository at this point in the history
  • Loading branch information
rodichenko committed Mar 10, 2022
1 parent e26be3a commit ec25820
Show file tree
Hide file tree
Showing 13 changed files with 197 additions and 74 deletions.
21 changes: 0 additions & 21 deletions client/public/hcs-image-viewer/LICENCE.viv.txt

This file was deleted.

2 changes: 1 addition & 1 deletion client/public/hcs-image-viewer/hcs-image-inject.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion client/public/hcs-image-viewer/hcs-image.js

Large diffs are not rendered by default.

40 changes: 40 additions & 0 deletions client/public/hcs-image-viewer/hcs-image.js.LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
object-assign
(c) Sindre Sorhus
@license MIT
*/

/* Copyright 2015-2018 Esri. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 @preserve */

/*! Hammer.JS - v2.0.7 - 2016-04-22
* http://hammerjs.github.io/
*
* Copyright (c) 2016 Jorik Tangelder;
* Licensed under the MIT license */

/** @license React v0.20.2
* scheduler.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

/** @license React v17.0.2
* react-dom.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

/** @license React v17.0.2
* react.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
7 changes: 7 additions & 0 deletions client/src/components/special/hcs-image/hcs-image.css
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,13 @@
width: 300px;
}

.download-tiff-row {
display: flex;
align-items: center;
justify-content: center;
margin: 5px;
}

.details-panel {
left: 5px;
max-width: 300px;
Expand Down
24 changes: 24 additions & 0 deletions client/src/components/special/hcs-image/hcs-image.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ import HcsImageControls from './hcs-image-controls';
import LoadingView from '../LoadingView';
import Panel from '../panel';
import HcsZPositionSelector from './hcs-z-position-selector';
import {
downloadAvailable as downloadCurrentTiffAvailable,
downloadCurrentTiff
} from './utilities/download-current-tiff';
import styles from './hcs-image.css';

@observer
Expand Down Expand Up @@ -417,11 +421,23 @@ class HcsImage extends React.PureComponent {
) {
return null;
}
const downloadAvailable = downloadCurrentTiffAvailable(this.hcsImageViewer);
if (!showConfiguration) {
return (
<div
className={styles.configurationActions}
>
<Button
className={styles.action}
size="small"
disabled={!downloadAvailable}
onClick={() => downloadCurrentTiff(this.hcsImageViewer)}
>
<Icon
type="camera"
className="cp-larger"
/>
</Button>
<Button
className={styles.action}
size="small"
Expand All @@ -442,6 +458,14 @@ class HcsImage extends React.PureComponent {
onClose={this.hideConfiguration}
>
<HcsImageControls />
<div className={styles.downloadTiffRow}>
<Button
disabled={!downloadAvailable}
onClick={() => downloadCurrentTiff(this.hcsImageViewer)}
>
Download current image
</Button>
</div>
</Panel>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright 2017-2022 EPAM Systems, Inc. (https://www.epam.com/)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

export function downloadAvailable (viewer) {
if (!viewer) {
return false;
}
const {
viewerState
} = viewer;
const {
loader,
pending
} = viewerState || {};
return !pending &&
loader &&
loader.length > 0;
}

export function downloadCurrentTiff (viewer) {
if (downloadAvailable(viewer)) {
viewer.makeSnapshot();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ function buildZPositionsArray (max, zSize, zUnit) {
}

class ViewerState {
@observable loader;
@observable use3D = false;
@observable useLens = false;
@observable useColorMap = false;
Expand Down Expand Up @@ -154,6 +155,7 @@ class ViewerState {
@action
onViewerStateChange = (viewer, newState) => {
const {
loader,
identifiers = [],
channels = [],
channelsVisibility = [],
Expand All @@ -178,6 +180,7 @@ class ViewerState {
metadata
} = newState || {};
this.pending = pending;
this.loader = loader;
if (pending) {
return;
}
Expand Down
4 changes: 1 addition & 3 deletions hcs-image-viewer/src/lib/state/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ import useSource from './utilities/use-source';
import useViewerState from './viewer-state';
import viewerActions from './viewer-state/actions';

export { default as HCSImageContext } from './context';

function initReducerState() {
return {};
}
Expand Down Expand Up @@ -102,4 +100,4 @@ function useHCSImageState() {
};
}

export { useHCSImageState };
export default useHCSImageState;
22 changes: 22 additions & 0 deletions hcs-image-viewer/src/lib/viewer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
* limitations under the License.
*/

import createSnapshot from './utilities/create-snapshot';

const LOG_MESSAGE = Symbol('log message');
const LOG_ERROR = Symbol('log error');
const CALLBACKS = Symbol('callbacks');
Expand Down Expand Up @@ -79,6 +81,7 @@ class Viewer {
this.verbose = verbose;
}
this.listeners = [];
this.container = container;
this.initializationPromise = new Promise((resolve, reject) => {
import(/* webpackChunkName: "hcs-image-inject" */ './hcs-image-wrapper')
.then(({ default: wrapper }) => {
Expand Down Expand Up @@ -272,6 +275,25 @@ class Viewer {
.catch(reject);
});
}

makeSnapshot(name) {
if (this.container) {
const canvas = this.container.getElementsByTagName('canvas')[0];
let imageName = name;
if (!imageName && this.viewerState && this.viewerState.metadata) {
const { metadata } = this.viewerState;
const {
ID,
Name,
} = metadata;
const parts = [ID, Name].filter(Boolean);
if (parts.length > 0) {
imageName = parts.join(' ');
}
}
createSnapshot(canvas, imageName);
}
}
}

export default Viewer;
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@
* limitations under the License.
*/

import React from 'react';
import DefaultState from './default';

const HCSImageContext = React.createContext(DefaultState);

export default HCSImageContext;
export default function createSnapshot(canvas, name = 'image') {
const dataUrl = canvas.toDataURL('image/png')
.replace('image/png', 'image/octet-stream');
const link = document.createElement('a');
link.download = `${name}.png`;
link.href = dataUrl;
link.click();
}
8 changes: 5 additions & 3 deletions hcs-image-viewer/src/lib/viewer/utilities/use-element-size.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@
* limitations under the License.
*/

import { useEffect, useState } from 'react';
import { useEffect, useRef, useState } from 'react';

export default function useElementSize(elementRef) {
const [size, setSize] = useState({ width: undefined, height: undefined });
const sizeRef = useRef(undefined);
useEffect(() => {
let width;
let height;
Expand All @@ -36,11 +37,12 @@ export default function useElementSize(elementRef) {
width = currentWidth;
height = currentHeight;
setSize({ width, height });
sizeRef.current = { width, height };
}
handle = requestAnimationFrame(callback);
};
callback();
return () => cancelAnimationFrame(handle);
}, [elementRef, setSize]);
return size;
}, [elementRef, setSize, sizeRef]);
return { size, sizeRef };
}
Loading

0 comments on commit ec25820

Please sign in to comment.