Support of context images for 2D tasks (#3122)
parent
975996ef62
commit
6f52ef30e4
@ -0,0 +1,74 @@
|
||||
// Copyright (C) 2021 Intel Corporation
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { notification } from 'antd';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { QuestionCircleOutlined, ShrinkOutlined } from '@ant-design/icons';
|
||||
import Spin from 'antd/lib/spin';
|
||||
import Image from 'antd/lib/image';
|
||||
|
||||
import { CombinedState } from 'reducers/interfaces';
|
||||
import { hideShowContextImage, getContextImage } from 'actions/annotation-actions';
|
||||
import CVATTooltip from 'components/common/cvat-tooltip';
|
||||
|
||||
export default function ContextImage(): JSX.Element | null {
|
||||
const dispatch = useDispatch();
|
||||
const { number: frame, hasRelatedContext } = useSelector((state: CombinedState) => state.annotation.player.frame);
|
||||
const { data: contextImageData, hidden: contextImageHidden, fetching: contextImageFetching } = useSelector(
|
||||
(state: CombinedState) => state.annotation.player.contextImage,
|
||||
);
|
||||
const [requested, setRequested] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (requested) {
|
||||
setRequested(false);
|
||||
}
|
||||
}, [frame]);
|
||||
|
||||
useEffect(() => {
|
||||
if (hasRelatedContext && !contextImageHidden && !requested) {
|
||||
dispatch(getContextImage());
|
||||
setRequested(true);
|
||||
}
|
||||
}, [contextImageHidden, requested, hasRelatedContext]);
|
||||
|
||||
if (!hasRelatedContext) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='cvat-context-image-wrapper' {...(contextImageHidden ? { style: { width: '32px' } } : {})}>
|
||||
<div className='cvat-context-image-wrapper-header' />
|
||||
{contextImageFetching ? <Spin size='small' /> : null}
|
||||
{contextImageHidden ? (
|
||||
<CVATTooltip title='A context image is available'>
|
||||
<QuestionCircleOutlined
|
||||
className='cvat-context-image-switcher'
|
||||
onClick={() => dispatch(hideShowContextImage(false))}
|
||||
/>
|
||||
</CVATTooltip>
|
||||
) : (
|
||||
<>
|
||||
<ShrinkOutlined
|
||||
className='cvat-context-image-switcher'
|
||||
onClick={() => dispatch(hideShowContextImage(true))}
|
||||
/>
|
||||
<Image
|
||||
{...(contextImageData ? { src: contextImageData } : {})}
|
||||
onError={() => {
|
||||
notification.error({
|
||||
message: 'Could not display context image',
|
||||
description: `Source is ${
|
||||
contextImageData === null ? 'empty' : contextImageData.slice(0, 100)
|
||||
}`,
|
||||
});
|
||||
}}
|
||||
className='cvat-context-image'
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -1,34 +0,0 @@
|
||||
// Copyright (C) 2021 Intel Corporation
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import React, { useEffect } from 'react';
|
||||
|
||||
interface Props {
|
||||
frame: number;
|
||||
contextImageHide: boolean;
|
||||
loaded: boolean;
|
||||
data: string;
|
||||
getContextImage(): void;
|
||||
}
|
||||
|
||||
export default function ContextImage(props: Props): JSX.Element {
|
||||
const {
|
||||
contextImageHide, loaded, data, getContextImage,
|
||||
} = props;
|
||||
|
||||
useEffect(() => {
|
||||
if (!contextImageHide && !loaded) {
|
||||
getContextImage();
|
||||
}
|
||||
}, [contextImageHide, loaded]);
|
||||
|
||||
if (!contextImageHide && data !== '') {
|
||||
return (
|
||||
<div className='cvat-contextImage'>
|
||||
<img src={data} alt='Context not available' className='cvat-contextImage-show' />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -1,37 +0,0 @@
|
||||
// Copyright (C) 2021 Intel Corporation
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import React from 'react';
|
||||
import CameraIcon from '@ant-design/icons/CameraOutlined';
|
||||
|
||||
import CVATTooltip from 'components/common/cvat-tooltip';
|
||||
import { Canvas3d as Canvas } from 'cvat-canvas3d-wrapper';
|
||||
import { ActiveControl } from 'reducers/interfaces';
|
||||
|
||||
interface Props {
|
||||
canvasInstance: Canvas;
|
||||
activeControl: ActiveControl;
|
||||
hideShowContextImage: (hidden: boolean) => void;
|
||||
contextImageHide: boolean;
|
||||
}
|
||||
|
||||
function PhotoContextControl(props: Props): JSX.Element {
|
||||
const { activeControl, contextImageHide, hideShowContextImage } = props;
|
||||
|
||||
return (
|
||||
<CVATTooltip title='Photo context show/hide' placement='right'>
|
||||
<CameraIcon
|
||||
className={`cvat-context-image-control
|
||||
cvat-control-side-bar-icon-size ${
|
||||
activeControl === ActiveControl.PHOTO_CONTEXT ? 'cvat-active-canvas-control' : ''
|
||||
}`}
|
||||
onClick={(): void => {
|
||||
hideShowContextImage(!contextImageHide);
|
||||
}}
|
||||
/>
|
||||
</CVATTooltip>
|
||||
);
|
||||
}
|
||||
|
||||
export default React.memo(PhotoContextControl);
|
||||
Loading…
Reference in New Issue