Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions client/src/components/annotators/ImageAnnotator.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ export default defineComponent({
type: Function as PropType<(imageDataItem: ImageDataItem, img: HTMLImageElement) => void>,
default: loadImageFunc,
},
// Range is [0, inf.)
brightness: {
type: Number as PropType<number | undefined>,
default: undefined,
},
},

setup(props) {
Expand Down Expand Up @@ -306,14 +311,24 @@ export default defineComponent({
setSpeed: unimplemented,
});

const setBrightnessFilter = (on: boolean) => {
if (local.quadFeature !== undefined) {
local.quadFeature.layer().node().css('filter', on ? 'url(#brightness)' : '');
}
};

if (local.imgs.length) {
const imgInternal = cacheFrame(0);
imgInternal.onloadPromise.then(() => {
initializeViewer(imgInternal.image.naturalWidth, imgInternal.image.naturalHeight);
const quadFeatureLayer = commonMedia.geoViewerRef.value.createLayer('feature', {
features: ['quad'],
autoshareRenderer: false,
});

// Set quadFeature and conditionally apply brightness filter
local.quadFeature = quadFeatureLayer.createFeature('quad');
setBrightnessFilter(props.brightness !== undefined);
seek(0);
data.ready = true;
});
Expand Down Expand Up @@ -341,18 +356,32 @@ export default defineComponent({
initializeViewer(imgInternal.image.naturalWidth, imgInternal.image.naturalHeight);
const quadFeatureLayer = commonMedia.geoViewerRef.value.createLayer('feature', {
features: ['quad'],
autoshareRenderer: false,
});

// Set quadFeature and conditionally apply brightness filter
local.quadFeature = quadFeatureLayer.createFeature('quad');
setBrightnessFilter(props.brightness !== undefined);
seek(0);
data.ready = true;
});
}
}

// Watch imageData for change
watch(toRef(props, 'imageData'), () => {
init();
});

// Watch brightness for change, only set filter if value
// is switching from number -> undefined, or vice versa.
watch(toRef(props, 'brightness'), (brightness, oldBrightness) => {
if ((brightness === undefined) !== (oldBrightness === undefined)) {
setBrightnessFilter(brightness !== undefined);
}
});


return {
data,
loadingVideo,
Expand All @@ -369,6 +398,30 @@ export default defineComponent({

<template>
<div class="video-annotator">
<svg
width="0"
height="0"
style="position: absolute; top: -1px; left: -1px"
>
<defs>
<filter id="brightness">
<feComponentTransfer color-interpolation-filters="sRGB">
<feFuncR
type="linear"
:slope="brightness"
/>
<feFuncG
type="linear"
:slope="brightness"
/>
<feFuncB
type="linear"
:slope="brightness"
/>
</feComponentTransfer>
</filter>
</defs>
</svg>
<div
ref="imageCursorRef"
class="imageCursor"
Expand Down
53 changes: 51 additions & 2 deletions client/src/components/annotators/VideoAnnotator.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts">
import {
defineComponent, onBeforeUnmount, PropType,
defineComponent, onBeforeUnmount, PropType, toRef, watch,
} from '@vue/composition-api';

import { Flick, SetTimeFunc } from 'vue-media-annotator/use/useTimeObserver';
Expand Down Expand Up @@ -93,6 +93,11 @@ export default defineComponent({
type: Number as PropType<number | null>,
default: null,
},
// Range is [0, inf.)
brightness: {
type: Number as PropType<number | undefined>,
default: undefined,
},
},

setup(props) {
Expand Down Expand Up @@ -186,6 +191,14 @@ export default defineComponent({
seek, play, pause, setVolume, setSpeed,
});

// eslint-disable-next-line @typescript-eslint/no-explicit-any
let quadFeatureLayer = undefined as any;
const setBrightnessFilter = (on: boolean) => {
if (quadFeatureLayer !== undefined) {
quadFeatureLayer.node().css('filter', on ? 'url(#brightness)' : '');
}
};

/**
* Initialize the Quad feature layer once
* video metadata has been fetched.
Expand All @@ -210,9 +223,12 @@ export default defineComponent({
data.maxFrame = maybeMaxFrame;
}
initializeViewer(width, height);
const quadFeatureLayer = commonMedia.geoViewerRef.value.createLayer('feature', {
quadFeatureLayer = commonMedia.geoViewerRef.value.createLayer('feature', {
features: ['quad.video'],
autoshareRenderer: false,
});

setBrightnessFilter(props.brightness !== undefined);
quadFeatureLayer
.createFeature('quad')
.data([
Expand All @@ -233,6 +249,14 @@ export default defineComponent({
data.duration = video.duration;
}

// Watch brightness for change, only set filter if value
// is switching from number -> undefined, or vice versa.
watch(toRef(props, 'brightness'), (brightness, oldBrightness) => {
if ((brightness === undefined) !== (oldBrightness === undefined)) {
setBrightnessFilter(brightness !== undefined);
}
});

function pendingUpdate() {
data.syncedFrame = Math.round(video.currentTime * props.frameRate);
}
Expand All @@ -241,6 +265,7 @@ export default defineComponent({
video.addEventListener('seeked', pendingUpdate);
video.addEventListener('error', logError);


return {
data,
imageCursorRef: commonMedia.imageCursorRef,
Expand All @@ -259,6 +284,30 @@ export default defineComponent({
class="video-annotator"
:style="{ cursor: data.cursor }"
>
<svg
width="0"
height="0"
style="position: absolute; top: -1px; left: -1px"
>
<defs>
<filter id="brightness">
<feComponentTransfer color-interpolation-filters="sRGB">
<feFuncR
type="linear"
:slope="brightness"
/>
<feFuncG
type="linear"
:slope="brightness"
/>
<feFuncB
type="linear"
:slope="brightness"
/>
</feComponentTransfer>
</filter>
</defs>
</svg>
<div
ref="imageCursorRef"
class="imageCursor"
Expand Down