optica-core 0.2.4 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -80,6 +80,11 @@ const canvas = useTemplateRef('canvas')
|
|
|
80
80
|
|
|
81
81
|
// image drawn on the canvas, the thumbnail first then the full image
|
|
82
82
|
let baseImage: HTMLImageElement = new Image()
|
|
83
|
+
// halved copies of baseImage (level i is 1/2^i of its size), drawn when zoomed out
|
|
84
|
+
// so the noise is averaged instead of aliased
|
|
85
|
+
let pyramid: CanvasImageSource[] = []
|
|
86
|
+
// no more halving below this size, in pixels
|
|
87
|
+
const PYRAMID_MIN_SIZE = 512
|
|
83
88
|
// incremented on each image change so late loads of a previous image are ignored
|
|
84
89
|
let loadToken = 0
|
|
85
90
|
|
|
@@ -97,7 +102,7 @@ function loadImage() {
|
|
|
97
102
|
if (token != loadToken) {
|
|
98
103
|
return
|
|
99
104
|
}
|
|
100
|
-
|
|
105
|
+
setBaseImage(first)
|
|
101
106
|
if (props.camera.zoom <= 0 || props.fitOnImageChange) {
|
|
102
107
|
screenFit()
|
|
103
108
|
}
|
|
@@ -112,7 +117,7 @@ function loadImage() {
|
|
|
112
117
|
full.alt = image.name
|
|
113
118
|
full.onload = () => {
|
|
114
119
|
if (token == loadToken) {
|
|
115
|
-
|
|
120
|
+
setBaseImage(full)
|
|
116
121
|
update()
|
|
117
122
|
}
|
|
118
123
|
}
|
|
@@ -123,6 +128,26 @@ function loadImage() {
|
|
|
123
128
|
first.src = image.thumbnail || image.image
|
|
124
129
|
}
|
|
125
130
|
|
|
131
|
+
function setBaseImage(image: HTMLImageElement) {
|
|
132
|
+
baseImage = image
|
|
133
|
+
pyramid = [image]
|
|
134
|
+
let prev: CanvasImageSource = image
|
|
135
|
+
let width = image.naturalWidth
|
|
136
|
+
let height = image.naturalHeight
|
|
137
|
+
while (width > PYRAMID_MIN_SIZE && height > PYRAMID_MIN_SIZE) {
|
|
138
|
+
width = Math.ceil(width / 2)
|
|
139
|
+
height = Math.ceil(height / 2)
|
|
140
|
+
const level = document.createElement('canvas')
|
|
141
|
+
level.width = width
|
|
142
|
+
level.height = height
|
|
143
|
+
const ctx = level.getContext('2d')!
|
|
144
|
+
ctx.imageSmoothingQuality = 'high'
|
|
145
|
+
ctx.drawImage(prev, 0, 0, width, height)
|
|
146
|
+
pyramid.push(level)
|
|
147
|
+
prev = level
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
126
151
|
loadImage()
|
|
127
152
|
|
|
128
153
|
watch(() => [props.image.name, props.image.image, props.image.thumbnail], loadImage)
|
|
@@ -253,7 +278,13 @@ function drawImage(c: HTMLCanvasElement) {
|
|
|
253
278
|
x: Math.max(0, (c.width - baseImage.naturalWidth * zoomX) / 2) / zoomX,
|
|
254
279
|
y: Math.max(0, (c.height - baseImage.naturalHeight * zoomY) / 2) / zoomY
|
|
255
280
|
}
|
|
256
|
-
|
|
281
|
+
// the smallest level still at least as detailed as the screen, the last downscale stays under 2x
|
|
282
|
+
const level = Math.max(0, Math.min(pyramid.length - 1, Math.floor(Math.log2(1 / Math.max(zoomX, zoomY)))))
|
|
283
|
+
const source = pyramid[level]
|
|
284
|
+
const sourceWidth = level == 0 ? baseImage.naturalWidth : (source as HTMLCanvasElement).width
|
|
285
|
+
const sourceHeight = level == 0 ? baseImage.naturalHeight : (source as HTMLCanvasElement).height
|
|
286
|
+
ctx.imageSmoothingQuality = 'high'
|
|
287
|
+
ctx.drawImage(source, 0, 0, sourceWidth, sourceHeight,
|
|
257
288
|
shiftCanvas.x, shiftCanvas.y, baseImage.naturalWidth, baseImage.naturalHeight)
|
|
258
289
|
|
|
259
290
|
const toCanvas = (pos: Coordinates): Coordinates => ({
|
|
@@ -46,7 +46,7 @@ export const POSITION_CSV_HEADER = ["X", "Y", "Z"]
|
|
|
46
46
|
|
|
47
47
|
export const DEFAULT_CSV_HEADER = [...LANDMARK_CSV_HEADER, ...POSE_CSV_HEADER, ...POSITION_CSV_HEADER]
|
|
48
48
|
|
|
49
|
-
// one CSV row (
|
|
49
|
+
// one CSV row (DEFAULT_CSV_HEADER), `group`: label of the distance or profile of the landmark
|
|
50
50
|
export function landmarkCSVRow(type: string, group: string, landmark: Landmark): string[] {
|
|
51
51
|
const { marker, image } = landmark.pose
|
|
52
52
|
const position = landmark.position
|