Skip to content

Commit

Permalink
Merge 3d3841e into 395bf77
Browse files Browse the repository at this point in the history
  • Loading branch information
knolleary committed Oct 29, 2020
2 parents 395bf77 + 3d3841e commit a6e687b
Show file tree
Hide file tree
Showing 6 changed files with 431 additions and 0 deletions.
13 changes: 13 additions & 0 deletions utility/annotate-image/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Copyright 2020 OpenJS Foundation and other contributors, https://openjsf.org/

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
72 changes: 72 additions & 0 deletions utility/annotate-image/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
node-red-node-annotate-image
==================

A <a href="http://nodered.org" target="_new">Node-RED</a> node that can annotate
a JPEG image.

The node is currently limited to drawing rectangles and circles over the image.
That can be used, for example, to annotate an image with bounding boxes of features
detected in the image by a TensorFlow node.

Install
-------

Run the following command in your Node-RED user directory - typically `~/.node-red`

npm install node-red-node-annotate-image


Usage
-----

The JPEG image should be passed to the node as a Buffer object under `msg.payload`.

The annotations are provided in <code>msg.annotations</code> and are applied in order.

Each annotation is an object with the following properties:

- `type` (*string*) : the type of the annotation - `rect` or `circle`
- `x`/`y` (*number*) : the top-left corner of a `rect` annotation, or the center of a `circle` annotation.
- `w`/`h` (*number*) : the width and height of a `rect` annotation
- `r` (*number*) : the radius of a `circle` annotation
- `bbox` (*array*) : this can be used instead of `x`, `y`, `w`, `h` and `r`.
It should be an array of four values giving the bounding box of the annotation:
`[x, y, w, h]`.
- `label` (*string*) : an optional piece of text to label the annotation with
- `stroke` (*string*) : the color of the annotation. Default: `#ffC000`
- `lineWidth` (*number*) : the stroke width used to draw the annotation. Default: `5`
- `fontSize` (*number*) : the font size to use for the label. Default: `24`
- `fontColor` (*string*) : the color of the font to use for the label. Default: `#ffC000`


Examples
--------

```javascript
msg.annotations = [ {
type: "rect",
x: 10, y: 10, w: 50, h: 50,
label: "hello"
}]
```
```javascript
msg.annotations = [
{
type: "circle",
x: 50, y: 50, r: 20,
lineWidth: 10

},
{
type: "rect",
x: 30, y: 30, w: 40, h: 40,
stroke: "blue"
}
]
```
```javascript
msg.annotations = [ {
type: "rect",
bbox: [ 10, 10, 50, 50]
}]
```
Binary file added utility/annotate-image/SourceSansPro-Regular.ttf
Binary file not shown.
165 changes: 165 additions & 0 deletions utility/annotate-image/annotate.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@

<script type="text/x-red" data-template-name="annotate-image">
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
</div>
<div id="node-input-row-stroke" class="form-row">
<label for="node-input-stroke">Stroke</label>
</div>
<div class="form-row">
<label for="node-input-lineWidth">Line Width</label>
<input type="text" id="node-input-lineWidth">
</div>
<div class="form-row">
<label for="node-input-fontSize">Font Size</label>
<input type="text" id="node-input-fontSize">
</div>
<div id="node-input-row-fontColor" class="form-row">
<label for="node-input-fontColor">Font Color</label>
</div>
</script>

<script type="text/x-red" data-help-name="annotate-image">
<p>A node that can annotate JPEG images with simple shapes and labels.</p>
<h3>Inputs</h3>
<dl class="message-properties">
<dt>payload<span class="property-type">Buffer</span></dt>
<dd>A Buffer containing a JPEG image. Support for PNG will come soon.</dd>
<dt>annotations<span class="property-type">Array</span></dt>
<dd>An array of annotations to apply to the image. See below for details
of the annotation format.</dd>
</dl>
<h3>Outputs</h3>
<dl class="message-properties">
<dt>payload<span class="property-type">Buffer</span></dt>
<dd>The image with any annotations applied.</dd>
</dl>
<h3>Details</h3>
<p>The annotations provided in <code>msg.annotations</code> are applied in order.
Each annotation is an object with the following properties:</p>
<dl class="message-properties">
<dt>type<span class="property-type">string</span></dt>
<dd><ul>
<li><code>"rect"</code> - draws a rectangle</li>
<li><code>"circle"</code> - draws a circle</li>
</dd>
<dt>x,y <span class="property-type">number</span></dt>
<dd>The top-left corner of a <code>rect</code> annotation, or the center of a <code>circle</code> annotation.</dd>
<dt>w,h <span class="property-type">number</span></dt>
<dd>The width and height of a <code>rect</code> annotation.</dd>
<dt>r <span class="property-type">number</span></dt>
<dd>The radius of a <code>circle</code> annotation.</dd>
<dt>bbox <span class="property-type">array</span></dt>
<dd>This can be used instead of <code>x</code>,<code>y</code>,<code>w</code>,<code>h</code> and <code>r</code>. It should
be an array of four values giving the bounding box of the annotation: <code>[x, y, w, h]</code>.</dd>
<dt>label <span class="property-type">string</span></dt>
<dd>An optional piece of text to label the annotation with</dd>
<dt>stroke <span class="property-type">string</span></dt>
<dd>Set the color of the annotation. Default: <code>"#ffC000"</code></dd>
<dt>lineWidth <span class="property-type">number</span></dt>
<dd>The stroke width used to draw the annotation. Default: <code>5</code></dd>
<dt>fontSize <span class="property-type">number</span></dt>
<dd>The font size to use for the label. Default: <code>24</code></dd>
<dt>fontColor <span class="property-type">string</span></dt>
<dd>The color of the font to use for the label. Default: <code>"#ffC000"</code></dd>
</dl>
<h3>Examples</h3>
<pre> msg.annotations = [ {
type: "rect",
x: 10, y: 10, w: 50, h: 50,
label: "hello"
}]</pre>
<pre> msg.annotations = [ {
type: "circle",
x: 50, y: 50, r: 20
}]</pre>
<pre> msg.annotations = [ {
type: "rect",
bbox: [ 10, 10, 50, 50]
}]</pre>
</script>

<script type="text/javascript">

(function() {
// Lifted from @node-red/editor-client/.../group.js
// Need to make this a default built-in palette so we don't have to copy
// it around.
var colorPalette = [
"#ff0000",
"#ffC000",
"#ffff00",
"#92d04f",
"#0070c0",
"#001f60",
"#6f2fa0",
"#000000",
"#777777"
]
var colorSteps = 3;
var colorCount = colorPalette.length;
for (var i=0,len=colorPalette.length*colorSteps;i<len;i++) {
var ci = i%colorCount;
var j = Math.floor(i/colorCount)+1;
var c = colorPalette[ci];
var r = parseInt(c.substring(1, 3), 16);
var g = parseInt(c.substring(3, 5), 16);
var b = parseInt(c.substring(5, 7), 16);
var dr = (255-r)/(colorSteps+((ci===colorCount-1) ?0:1));
var dg = (255-g)/(colorSteps+((ci===colorCount-1) ?0:1));
var db = (255-b)/(colorSteps+((ci===colorCount-1) ?0:1));
r = Math.min(255,Math.floor(r+j*dr));
g = Math.min(255,Math.floor(g+j*dg));
b = Math.min(255,Math.floor(b+j*db));
var s = ((r<<16) + (g<<8) + b).toString(16);
colorPalette.push('#'+'000000'.slice(0, 6-s.length)+s);
}




RED.nodes.registerType('annotate-image',{
category: 'utility',
color:"#f1c2f0",
defaults: {
name: {value:""},
fill: {value:""},
stroke: {value:"#ffC000"},
lineWidth: {value:5},
fontSize: {value: 24},
fontColor: {value: "#ffC000"}

},
inputs:1,
outputs:1,
icon: "font-awesome/fa-object-group",
label: function() {
return this.name||"Annotate Image";
},
labelStyle: function() {
return this.name?"node_label_italic":"";
},
oneditprepare: function() {
RED.colorPicker.create({
id:"node-input-stroke",
value: this.stroke || "#ffC000",
palette: colorPalette,
cellPerRow: colorCount,
cellWidth: 16,
cellHeight: 16,
cellMargin: 3
}).appendTo("#node-input-row-stroke");
RED.colorPicker.create({
id:"node-input-fontColor",
value: this.fontColor || "#ffC000",
palette: colorPalette,
cellPerRow: colorCount,
cellWidth: 16,
cellHeight: 16,
cellMargin: 3
}).appendTo("#node-input-row-fontColor");
}
});
})();
</script>

0 comments on commit a6e687b

Please sign in to comment.