未验证 提交 c6ed6d12 编写于 作者: B Boris Sekachev 提交者: GitHub

Added smooth image option (#3933)

上级 c787f049
......@@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add Cityscapes format (<https://github.com/openvinotoolkit/cvat/pull/3758>)
- Add Open Images V6 format (<https://github.com/openvinotoolkit/cvat/pull/3679>)
- Rotated bounding boxes (<https://github.com/openvinotoolkit/cvat/pull/3832>)
- Player option: Smooth image when zoom-in, enabled by default (<https://github.com/openvinotoolkit/cvat/pull/3933>)
### Changed
- TDB
......
{
"name": "cvat-canvas",
"version": "2.9.1",
"version": "2.10.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "cvat-canvas",
"version": "2.9.1",
"version": "2.10.0",
"license": "MIT",
"dependencies": {
"svg.draggable.js": "2.2.2",
......
{
"name": "cvat-canvas",
"version": "2.9.1",
"version": "2.10.0",
"description": "Part of Computer Vision Annotation Tool which presents its canvas library",
"main": "src/canvas.ts",
"scripts": {
......
......@@ -229,6 +229,17 @@ polyline.cvat_canvas_shape_splitting {
}
}
.cvat_canvas_pixelized {
image-rendering: optimizeSpeed; /* Legal fallback */
image-rendering: -moz-crisp-edges; /* Firefox */
image-rendering: -o-crisp-edges; /* Opera */
image-rendering: -webkit-optimize-contrast; /* Safari */
image-rendering: optimize-contrast; /* CSS3 Proposed */
image-rendering: crisp-edges; /* CSS4 Proposed */
image-rendering: pixelated; /* CSS4 Proposed */
-ms-interpolation-mode: nearest-neighbor; /* IE8+ */
}
#cvat_canvas_wrapper {
width: calc(100% - 10px);
height: calc(100% - 10px);
......@@ -273,6 +284,8 @@ polyline.cvat_canvas_shape_splitting {
}
#cvat_canvas_bitmap {
@extend .cvat_canvas_pixelized;
pointer-events: none;
position: absolute;
z-index: 4;
......
......@@ -52,6 +52,7 @@ export enum CuboidDrawingMethod {
}
export interface Configuration {
smoothImage?: boolean;
autoborders?: boolean;
displayAllText?: boolean;
undefinedAttrValue?: string;
......@@ -652,23 +653,21 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
if (typeof configuration.autoborders === 'boolean') {
this.data.configuration.autoborders = configuration.autoborders;
}
if (typeof configuration.smoothImage === 'boolean') {
this.data.configuration.smoothImage = configuration.smoothImage;
}
if (typeof configuration.undefinedAttrValue === 'string') {
this.data.configuration.undefinedAttrValue = configuration.undefinedAttrValue;
}
if (typeof configuration.forceDisableEditing === 'boolean') {
this.data.configuration.forceDisableEditing = configuration.forceDisableEditing;
}
if (typeof configuration.intelligentPolygonCrop === 'boolean') {
this.data.configuration.intelligentPolygonCrop = configuration.intelligentPolygonCrop;
}
if (typeof configuration.forceFrameUpdate === 'boolean') {
this.data.configuration.forceFrameUpdate = configuration.forceFrameUpdate;
}
if (typeof configuration.creationOpacity === 'number') {
this.data.configuration.creationOpacity = configuration.creationOpacity;
}
......
......@@ -1169,15 +1169,16 @@ export class CanvasViewImpl implements CanvasView, Listener {
if (reason === UpdateReasons.CONFIG_UPDATED) {
const { activeElement } = this;
this.deactivate();
const { configuration } = model;
if (model.configuration.displayAllText && !this.configuration.displayAllText) {
if (configuration.displayAllText && !this.configuration.displayAllText) {
for (const i in this.drawnStates) {
if (!(i in this.svgTexts)) {
this.svgTexts[i] = this.addText(this.drawnStates[i]);
this.updateTextPosition(this.svgTexts[i], this.svgShapes[i]);
}
}
} else if (model.configuration.displayAllText === false && this.configuration.displayAllText) {
} else if (configuration.displayAllText === false && this.configuration.displayAllText) {
for (const i in this.drawnStates) {
if (i in this.svgTexts && Number.parseInt(i, 10) !== activeElement.clientID) {
this.svgTexts[i].remove();
......@@ -1186,7 +1187,15 @@ export class CanvasViewImpl implements CanvasView, Listener {
}
}
this.configuration = model.configuration;
if ('smoothImage' in configuration) {
if (configuration.smoothImage) {
this.background.classList.remove('cvat_canvas_pixelized');
} else {
this.background.classList.add('cvat_canvas_pixelized');
}
}
this.configuration = configuration;
this.activate(activeElement);
this.editHandler.configurate(this.configuration);
this.drawHandler.configurate(this.configuration);
......
{
"name": "cvat-ui",
"version": "1.26.0",
"version": "1.27.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "cvat-ui",
"version": "1.26.0",
"version": "1.27.0",
"license": "MIT",
"dependencies": {
"@ant-design/icons": "^4.6.3",
......
{
"name": "cvat-ui",
"version": "1.26.0",
"version": "1.27.0",
"description": "CVAT single-page application",
"main": "src/index.tsx",
"scripts": {
......
......@@ -22,6 +22,7 @@ export enum SettingsActionTypes {
CHANGE_FRAME_STEP = 'CHANGE_FRAME_STEP',
CHANGE_FRAME_SPEED = 'CHANGE_FRAME_SPEED',
SWITCH_RESET_ZOOM = 'SWITCH_RESET_ZOOM',
SWITCH_SMOOTH_IMAGE = 'SWITCH_SMOOTH_IMAGE',
CHANGE_BRIGHTNESS_LEVEL = 'CHANGE_BRIGHTNESS_LEVEL',
CHANGE_CONTRAST_LEVEL = 'CHANGE_CONTRAST_LEVEL',
CHANGE_SATURATION_LEVEL = 'CHANGE_SATURATION_LEVEL',
......@@ -166,6 +167,15 @@ export function switchResetZoom(resetZoom: boolean): AnyAction {
};
}
export function switchSmoothImage(enabled: boolean): AnyAction {
return {
type: SettingsActionTypes.SWITCH_SMOOTH_IMAGE,
payload: {
smoothImage: enabled,
},
};
}
export function changeBrightnessLevel(level: number): AnyAction {
return {
type: SettingsActionTypes.CHANGE_BRIGHTNESS_LEVEL,
......
......@@ -27,7 +27,7 @@ const MAX_DISTANCE_TO_OPEN_SHAPE = 50;
interface Props {
sidebarCollapsed: boolean;
canvasInstance: Canvas | Canvas3d;
canvasInstance: Canvas | Canvas3d | null;
jobInstance: any;
activatedStateID: number | null;
activatedAttributeID: number | null;
......@@ -57,6 +57,7 @@ interface Props {
contrastLevel: number;
saturationLevel: number;
resetZoom: boolean;
smoothImage: boolean;
aamZoomMargin: number;
showObjectsTextAlways: boolean;
showAllInterpolationTracks: boolean;
......@@ -105,6 +106,7 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
workspace,
showProjections,
selectedOpacity,
smoothImage,
} = this.props;
const { canvasInstance } = this.props as { canvasInstance: Canvas };
......@@ -114,6 +116,7 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
wrapper.appendChild(canvasInstance.html());
canvasInstance.configure({
smoothImage,
autoborders: automaticBordering,
undefinedAttrValue: consts.UNDEFINED_ATTRIBUTE_VALUE,
displayAllText: showObjectsTextAlways,
......@@ -144,6 +147,7 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
activatedStateID,
curZLayer,
resetZoom,
smoothImage,
grid,
gridSize,
gridOpacity,
......@@ -167,7 +171,8 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
prevProps.automaticBordering !== automaticBordering ||
prevProps.showProjections !== showProjections ||
prevProps.intelligentPolygonCrop !== intelligentPolygonCrop ||
prevProps.selectedOpacity !== selectedOpacity
prevProps.selectedOpacity !== selectedOpacity ||
prevProps.smoothImage !== smoothImage
) {
canvasInstance.configure({
undefinedAttrValue: consts.UNDEFINED_ATTRIBUTE_VALUE,
......@@ -176,6 +181,7 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
showProjections,
intelligentPolygonCrop,
creationOpacity: selectedOpacity,
smoothImage,
});
}
......@@ -418,7 +424,9 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
private fitCanvas = (): void => {
const { canvasInstance } = this.props;
canvasInstance.fitCanvas();
if (canvasInstance) {
canvasInstance.fitCanvas();
}
};
private onCanvasMouseDown = (e: MouseEvent): void => {
......@@ -677,7 +685,7 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
curZLayer, annotations, frameData, canvasInstance,
} = this.props;
if (frameData !== null) {
if (frameData !== null && canvasInstance) {
canvasInstance.setup(
frameData,
annotations.filter((e) => e.objectType !== ObjectType.TAG),
......
......@@ -24,12 +24,14 @@ interface Props {
frameSpeed: FrameSpeed;
resetZoom: boolean;
rotateAll: boolean;
smoothImage: boolean;
canvasBackgroundColor: string;
onChangeFrameStep(step: number): void;
onChangeFrameSpeed(speed: FrameSpeed): void;
onSwitchResetZoom(enabled: boolean): void;
onSwitchRotateAll(rotateAll: boolean): void;
onChangeCanvasBackgroundColor(color: string): void;
onSwitchSmoothImage(enabled: boolean): void;
}
export default function PlayerSettingsComponent(props: Props): JSX.Element {
......@@ -38,11 +40,13 @@ export default function PlayerSettingsComponent(props: Props): JSX.Element {
frameSpeed,
resetZoom,
rotateAll,
smoothImage,
canvasBackgroundColor,
onChangeFrameStep,
onChangeFrameSpeed,
onSwitchResetZoom,
onSwitchRotateAll,
onSwitchSmoothImage,
onChangeCanvasBackgroundColor,
} = props;
......@@ -176,6 +180,26 @@ export default function PlayerSettingsComponent(props: Props): JSX.Element {
</Row>
</Col>
</Row>
<Row justify='start'>
<Col span={7}>
<Row className='cvat-player-settings-smooth-image'>
<Col span={24} className='cvat-player-settings-smooth-image-checkbox'>
<Checkbox
className='cvat-text-color'
checked={smoothImage}
onChange={(event: CheckboxChangeEvent): void => {
onSwitchSmoothImage(event.target.checked);
}}
>
Smooth image
</Checkbox>
</Col>
<Col span={24}>
<Text type='secondary'> Smooth image when zoom-in it </Text>
</Col>
</Row>
</Col>
</Row>
</div>
);
}
......@@ -53,7 +53,7 @@ import { Canvas3d } from 'cvat-canvas3d-wrapper';
interface StateToProps {
sidebarCollapsed: boolean;
canvasInstance: Canvas | Canvas3d;
canvasInstance: Canvas | Canvas3d | null;
jobInstance: any;
activatedStateID: number | null;
activatedAttributeID: number | null;
......@@ -80,6 +80,7 @@ interface StateToProps {
contrastLevel: number;
saturationLevel: number;
resetZoom: boolean;
smoothImage: boolean;
aamZoomMargin: number;
showObjectsTextAlways: boolean;
showAllInterpolationTracks: boolean;
......@@ -155,6 +156,7 @@ function mapStateToProps(state: CombinedState): StateToProps {
contrastLevel,
saturationLevel,
resetZoom,
smoothImage,
},
workspace: {
aamZoomMargin,
......@@ -201,6 +203,7 @@ function mapStateToProps(state: CombinedState): StateToProps {
contrastLevel: contrastLevel / 100,
saturationLevel: saturationLevel / 100,
resetZoom,
smoothImage,
aamZoomMargin,
showObjectsTextAlways,
showAllInterpolationTracks,
......
......@@ -11,6 +11,7 @@ import {
switchResetZoom,
switchRotateAll,
changeCanvasBackgroundColor,
switchSmoothImage,
} from 'actions/settings-actions';
import { CombinedState, FrameSpeed } from 'reducers/interfaces';
......@@ -19,6 +20,7 @@ interface StateToProps {
frameSpeed: FrameSpeed;
resetZoom: boolean;
rotateAll: boolean;
smoothImage: boolean;
canvasBackgroundColor: string;
}
......@@ -28,6 +30,7 @@ interface DispatchToProps {
onSwitchResetZoom(enabled: boolean): void;
onSwitchRotateAll(rotateAll: boolean): void;
onChangeCanvasBackgroundColor(color: string): void;
onSwitchSmoothImage(enabled: boolean): void;
}
function mapStateToProps(state: CombinedState): StateToProps {
......@@ -55,6 +58,9 @@ function mapDispatchToProps(dispatch: any): DispatchToProps {
onChangeCanvasBackgroundColor(color: string): void {
dispatch(changeCanvasBackgroundColor(color));
},
onSwitchSmoothImage(enabled: boolean): void {
dispatch(switchSmoothImage(enabled));
},
};
}
......
......@@ -617,6 +617,7 @@ export interface PlayerSettingsState {
frameSpeed: FrameSpeed;
resetZoom: boolean;
rotateAll: boolean;
smoothImage: boolean;
grid: boolean;
gridSize: number;
gridColor: GridColor;
......
......@@ -43,6 +43,7 @@ const defaultState: SettingsState = {
frameSpeed: FrameSpeed.Usual,
resetZoom: false,
rotateAll: false,
smoothImage: true,
grid: false,
gridSize: 100,
gridColor: GridColor.White,
......@@ -183,6 +184,15 @@ export default (state = defaultState, action: AnyAction): SettingsState => {
},
};
}
case SettingsActionTypes.SWITCH_SMOOTH_IMAGE: {
return {
...state,
player: {
...state.player,
smoothImage: action.payload.smoothImage,
},
};
}
case SettingsActionTypes.CHANGE_BRIGHTNESS_LEVEL: {
return {
...state,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册