Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
I
image-annotation
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Miguel Reboiro Jato
image-annotation
Commits
0eb88088
Commit
0eb88088
authored
Feb 12, 2025
by
Administrator
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Adds annotation components
parent
65d488d7
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
277 additions
and
527 deletions
+277
-527
package-lock.json
package-lock.json
+71
-191
app.component.html
src/app/app.component.html
+0
-335
app.routes.ts
src/app/app.routes.ts
+4
-1
annotation.component.html
src/app/components/annotation/annotation.component.html
+3
-0
annotation.component.scss
src/app/components/annotation/annotation.component.scss
+0
-0
annotation.component.spec.ts
src/app/components/annotation/annotation.component.spec.ts
+23
-0
annotation.component.ts
src/app/components/annotation/annotation.component.ts
+51
-0
annotator.component.html
src/app/components/annotator/annotator.component.html
+4
-0
annotator.component.scss
src/app/components/annotator/annotator.component.scss
+5
-0
annotator.component.spec.ts
src/app/components/annotator/annotator.component.spec.ts
+23
-0
annotator.component.ts
src/app/components/annotator/annotator.component.ts
+93
-0
No files found.
package-lock.json
View file @
0eb88088
This diff is collapsed.
Click to expand it.
src/app/app.component.html
View file @
0eb88088
This diff is collapsed.
Click to expand it.
src/app/app.routes.ts
View file @
0eb88088
import
{
Routes
}
from
'@angular/router'
;
import
{
Routes
}
from
'@angular/router'
;
import
{
AnnotationComponent
}
from
'./components/annotation/annotation.component'
;
export
const
routes
:
Routes
=
[];
export
const
routes
:
Routes
=
[
{
path
:
""
,
component
:
AnnotationComponent
}
];
src/app/components/annotation/annotation.component.html
0 → 100644
View file @
0eb88088
<div
id=
"dropZone"
(
drop
)="
onUploadImage
($
event
)"
(
dragover
)="
onDragOver
($
event
)"
>
<amc-annotator
#
annotator
></amc-annotator>
</div>
src/app/components/annotation/annotation.component.scss
0 → 100644
View file @
0eb88088
src/app/components/annotation/annotation.component.spec.ts
0 → 100644
View file @
0eb88088
import
{
ComponentFixture
,
TestBed
}
from
'@angular/core/testing'
;
import
{
AnnotationComponent
}
from
'./annotation.component'
;
describe
(
'AnnotationComponent'
,
()
=>
{
let
component
:
AnnotationComponent
;
let
fixture
:
ComponentFixture
<
AnnotationComponent
>
;
beforeEach
(
async
()
=>
{
await
TestBed
.
configureTestingModule
({
imports
:
[
AnnotationComponent
]
})
.
compileComponents
();
fixture
=
TestBed
.
createComponent
(
AnnotationComponent
);
component
=
fixture
.
componentInstance
;
fixture
.
detectChanges
();
});
it
(
'should create'
,
()
=>
{
expect
(
component
).
toBeTruthy
();
});
});
src/app/components/annotation/annotation.component.ts
0 → 100644
View file @
0eb88088
import
{
Component
,
ElementRef
,
ViewChild
}
from
'@angular/core'
;
import
{
AnnotatorComponent
}
from
"../annotator/annotator.component"
;
@
Component
({
selector
:
'amc-annotation'
,
standalone
:
true
,
imports
:
[
AnnotatorComponent
],
templateUrl
:
'./annotation.component.html'
,
styleUrl
:
'./annotation.component.scss'
})
export
class
AnnotationComponent
{
@
ViewChild
(
"annotator"
,
{
static
:
true
})
private
annotator
!
:
AnnotatorComponent
;
public
onUploadImage
(
event
:
DragEvent
):
void
{
console
.
log
(
this
.
annotator
);
event
.
preventDefault
();
const
file
=
event
.
dataTransfer
?.
files
[
0
];
if
(
file
&&
file
.
type
.
startsWith
(
"image/"
))
{
console
.
log
(
file
);
const
reader
=
new
FileReader
();
reader
.
onload
=
(
event
:
ProgressEvent
<
FileReader
>
)
=>
{
console
.
log
(
"Read"
);
const
image
=
new
Image
();
image
.
onload
=
(
event
:
Event
)
=>
{
this
.
annotator
.
changeImage
(
image
);
}
if
(
typeof
(
event
.
target
?.
result
)
===
"string"
)
{
image
.
src
=
event
.
target
.
result
;
}
};
reader
.
readAsDataURL
(
file
);
}
else
{
alert
(
"Only images are supported"
);
}
}
public
onDragOver
(
event
:
DragEvent
):
void
{
event
.
preventDefault
();
console
.
log
(
typeof
(
event
));
}
}
src/app/components/annotator/annotator.component.html
0 → 100644
View file @
0eb88088
<canvas
#
annotator
id=
"annotator"
(
mousedown
)="
onMouseDown
($
event
)"
(
mousemove
)="
onMouseMove
($
event
)"
(
mouseup
)="
onMouseUp
($
event
)"
></canvas>
\ No newline at end of file
src/app/components/annotator/annotator.component.scss
0 → 100644
View file @
0eb88088
canvas
#annotator
{
background-color
:
red
;
max-width
:
800px
;
max-height
:
600px
;
}
\ No newline at end of file
src/app/components/annotator/annotator.component.spec.ts
0 → 100644
View file @
0eb88088
import
{
ComponentFixture
,
TestBed
}
from
'@angular/core/testing'
;
import
{
AnnotatorComponent
}
from
'./annotator.component'
;
describe
(
'AnnotatorComponent'
,
()
=>
{
let
component
:
AnnotatorComponent
;
let
fixture
:
ComponentFixture
<
AnnotatorComponent
>
;
beforeEach
(
async
()
=>
{
await
TestBed
.
configureTestingModule
({
imports
:
[
AnnotatorComponent
]
})
.
compileComponents
();
fixture
=
TestBed
.
createComponent
(
AnnotatorComponent
);
component
=
fixture
.
componentInstance
;
fixture
.
detectChanges
();
});
it
(
'should create'
,
()
=>
{
expect
(
component
).
toBeTruthy
();
});
});
src/app/components/annotator/annotator.component.ts
0 → 100644
View file @
0eb88088
import
{
Component
,
ElementRef
,
ViewChild
}
from
'@angular/core'
;
@
Component
({
selector
:
'amc-annotator'
,
standalone
:
true
,
imports
:
[],
templateUrl
:
'./annotator.component.html'
,
styleUrl
:
'./annotator.component.scss'
})
export
class
AnnotatorComponent
{
@
ViewChild
(
"annotator"
,
{
static
:
true
})
public
canvas
!
:
ElementRef
<
HTMLCanvasElement
>
;
private
startPoint
?:
[
number
,
number
];
private
backgroundImage
?:
HTMLImageElement
;
private
isDrawing
():
boolean
{
return
this
.
startPoint
!==
undefined
;
}
private
getCanvasContext
():
CanvasRenderingContext2D
{
const
context
=
this
.
canvas
.
nativeElement
.
getContext
(
"2d"
);
if
(
context
===
null
)
{
throw
new
Error
(
"canvas is not initialized"
);
}
else
{
return
context
;
}
}
public
changeImage
(
image
:
HTMLImageElement
):
void
{
this
.
backgroundImage
=
image
;
this
.
repaintImage
();
}
private
repaintImage
():
void
{
const
canvas
=
this
.
canvas
.
nativeElement
;
if
(
this
.
backgroundImage
===
undefined
)
{
const
context
=
this
.
getCanvasContext
();
context
.
clearRect
(
0
,
0
,
canvas
.
width
,
canvas
.
height
);
}
else
{
canvas
.
width
=
this
.
backgroundImage
.
width
;
canvas
.
height
=
this
.
backgroundImage
.
height
;
const
context
=
this
.
getCanvasContext
();
context
.
clearRect
(
0
,
0
,
canvas
.
width
,
canvas
.
height
);
context
.
drawImage
(
this
.
backgroundImage
,
0
,
0
,
canvas
.
width
,
canvas
.
height
);
}
}
public
onMouseDown
(
event
:
MouseEvent
):
void
{
this
.
startPoint
=
[
event
.
offsetX
,
event
.
offsetY
];
}
public
onMouseMove
(
event
:
MouseEvent
):
void
{
if
(
this
.
isDrawing
()
&&
this
.
startPoint
!==
undefined
)
{
const
[
x0
,
y0
]
=
this
.
startPoint
;
const
[
x
,
y
,
width
,
height
]
=
this
.
adjustCoordinates
(
x0
,
y0
,
event
.
clientX
-
x0
,
event
.
clientY
-
y0
);
const
canvas
=
this
.
canvas
.
nativeElement
;
const
context
=
this
.
getCanvasContext
();
this
.
repaintImage
();
context
.
globalCompositeOperation
=
"xor"
;
context
.
strokeStyle
=
"black"
;
context
.
lineWidth
=
Math
.
ceil
(
Math
.
max
(
canvas
.
width
,
canvas
.
height
)
/
500
);
context
.
beginPath
();
context
.
rect
(
x
,
y
,
width
,
height
);
context
.
stroke
();
}
}
private
adjustCoordinates
(
x
:
number
,
y
:
number
,
width
:
number
,
height
:
number
):
[
number
,
number
,
number
,
number
]
{
const
canvas
=
this
.
canvas
.
nativeElement
;
if
(
canvas
.
width
===
canvas
.
clientWidth
&&
canvas
.
height
===
canvas
.
clientHeight
)
{
return
[
x
,
y
,
width
,
height
];
}
else
{
return
[
x
*
canvas
.
width
/
canvas
.
clientWidth
,
y
*
canvas
.
height
/
canvas
.
clientHeight
,
width
*
canvas
.
width
/
canvas
.
clientWidth
,
height
*
canvas
.
height
/
canvas
.
clientHeight
];
}
}
public
onMouseUp
(
event
:
MouseEvent
):
void
{
this
.
startPoint
=
undefined
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment