Drawing graphics on canvas in node-js/Express - node.js

I want to draw a chart on canvas element. My Jade file contains following:
div
canvas
In my index.js file in node.js web application, I tried the following:
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
context.beginPath();
context.strokeStyle = "rgba(255, 0, 0, 1)";
height = canvas.height;
width = canvas.width;
context.moveTo(0, 0);
context.lineTo(width, height);
context.lineWidth = 1;
context.stroke();
However, it fails to recognize "document". My question is how do I obtain the reference to "canvas" in my .js file? Note that the actual chart would be more complex than the simple line drawing code shown above for brevity. The data for the chart is generated in index.js file at the server end. So the chart will be created on the server.

NodeJS cannot get a reference to the users browser to draw on the displayed page. Although it is Javascript, NodeJS executes on the server side. The same code will have to be written within your HTML page.
If your drawing needs some data to come from the backend NodeJS logic, then the page Javascript will have to invoke your NodeJS services to fetch the relevant data.

As of August 2021, it's possible to draw on Canvas in Node.js by using
https://github.com/Automattic/node-canvas

Related

Getting image from dicom .DCM file in node.js

I would like to generate a thumbnail image from a .dcm file (Dicom) in node.js.
So far I've found a node modules called dicom-parser that extracts the metadata from a dcm file.
My test case :
var dicom = require('dicom-parser');
var fs = require('fs');
var dicomFileAsBuffer = fs.readFileSync('./FullPano.dcm');
var dataSet = dicom.parseDicom(dicomFileAsBuffer);
var pixelData = new Uint8Array(dataSet.byteArray.buffer,
dataSet.elements.x00880200.items[0].dataSet.elements.x7fe00010.dataOffset,
dataSet.elements.x00880200.items[0].dataSet.elements.x7fe00010.length);
fs.writeFileSync('test5.jpg', pixelData); // <----- not working :'(
To help you help me debug, here is the dataSet.elements.x00880200 object :
But the pixelData stored in the tag x00880200 -> x7fe00010 is not in a standard format, either jpeg, jpg, png... The idea here is to get the thumbnail of a dcm image directly from a file, on the fly, server-side in nodejs.
From the dicom doc (see below), the tag 0088,0200 holds the data for the icon, aka thumbnail.
Icon Image Sequence
(0088,0200)
3
This icon image is representative of the Image.
Only a single Item is permitted in this Sequence.
I've come around the cornerstone libs : cornerstone-js and wado-image-loader. But neither are working in a node.js environment (made an issue about that). These libs can generate the "main" image of a dcm, but only once the dcm file is loaded on the cliend-side, in js. My requirement is to do that in nodejs, for the icon/thumbnail.
If you are trying to save the image icon as a JPG, that may be your issue:
Only monochrome and palette color images shall be used. Samples per Pixel (0028,0002) shall have a Value of 1, Photometric Interpretation (0028,0004) shall have a Value of either MONOCHROME 1, MONOCHROME 2 or PALETTE COLOR, Planar Configuration (0028,0006) shall not be present.source
I'm not familiar with node.js, but the data in the Icon Image Sequence may not be appropriate for that call.
Note also that you are getting an optional, small, thumbnail of the image, not the actual image data, which can be found in the Pixel Data attribute (7FE0,0010).
A bit late but, if you are still looking for an answer, you can use dcmjs-imaging (full disclosure, I am the author). The library implements a DICOM image and overlay rendering pipeline, for Node.js and browser.
The library supports uncompressed data but also, optionally, decodes all major transfer syntaxes using a native WebAssembly module.
Given that you have already fetched the the DICOM bytes in an ArrayBuffer, you can use the following Node.js example to render the image in an RGBA pixel ArrayBuffer.
// Import objects
const dcmjsImaging = require('dcmjs-imaging');
const { DicomImage, NativePixelDecoder } = dcmjsImaging;
// Optionally register native decoders WebAssembly.
// If native decoders are not registered, only
// uncompressed syntaxes would be able to be rendered.
await NativePixelDecoder.initializeAsync();
// Create an ArrayBuffer with the contents of the DICOM P10 byte stream.
const image = new DicomImage(arrayBuffer);
// Render image.
const renderingResult = image.render();
// Rendered pixels in an RGBA ArrayBuffer.
const renderedPixels = renderingResult.pixels;
// Rendered width.
const width = renderingResult.width;
// Rendered height.
const height = renderingResult.height;

Converting groups/layers in fabricjs to image

Im currently looking into fabric.js as well as konva.js and fabric.js seems to have the advantage not to have to implement all selection tools manually; However while in konva.js it is quite obvious how to extract an image "projection" of a layer (as each layer there has at least one canvas on its own), I dont know if difficult it is to convert a group in fabric.js into an image (not svg!). Basically I need some output object which I can convert into a bitmap of certain size for further processing steps.
Thank you for any help :)!
So each object in fabric, including the Groups of object comes with a toDataUrl method.
In this basic basic example i create a fabricJS circle, i do not add it to a canvas, i just exec its own dataURL method.
Before i add a scale factor just to make it bigger.
var circle = new fabric.Circle({radius: 50, fill: 'blue', stroke: 'red'});
circle.scaleX = 20;
circle.scaleY = 20;
document.getElementById('i').src = circle.toDataURL();
<script src="https://rawgithub.com/kangax/fabric.js/master/dist/fabric.js"></script>
<img id="i" />
You can use fabric's built-in cloneAsImage function:
group.cloneAsImage(image => {
image.set({...do settings});
canvas.add(image);
});
see more here: http://fabricjs.com/docs/fabric.Group.html#cloneAsImage

Use of custom filters in Fabric JS - getting the original back

I have been playing with custom filters in Fabric JS. But I just don't know how to undo anything done. Seems the pixels get overwritten by the process, which is fine, but how do I go back to the orginal? The code project starter is here:
https://github.com/pixolith/fabricjs-async-web-worker-filters
So, in the custom filter, the results are placed into the canvas as follows:
imageDataArray.forEach( function( data ) {
cacheCtx.putImageData( data.data, 0, data.blocks );
} );
That shows the processed image in the render. But I don't understand how to "get back" the original. I have tried this before the processing:
var obj = canvas.getActiveObject();
var originalSource = obj._originalElement.currentSrc; // restore the original since filters trash the canvas
obj.filters[index] = filter;
obj.applyFilters(canvas.renderAll.bind(canvas));
But it does not "get it back". I really don't wish to reload the image each time as they can be large at times. Any help appreciated.
As you noted obj._originalElement is the ORIGINAL element of the image you first loaded. No reason to reload it at all, you have it there. Ready to be smashed on canvas.
So just do obj.element = obj._originalElement and you are back to original after a canvas.renderAll();

Fabricjs canvas objects not rendering properly

I need help with fabricjs, objects are not rendering properly while I clone and shrink to another canvas.
If I do only with text object there is not problem kindly look the below fiddle (after save)
enter code hereFIDDLE
If I load an image then the objects not aligning properly.
enter code hereFIDDLE
Kindly help to resolve form this.
Thank You.
Your problem for the image not respecting the zoom is that the image loads asyncronously. So you load from json, you do the zoom logic, some microseconds later the image finish loading and sets its own width and height.
Other than this you have to use zoom the right way.
Everyone is scaling manually and changing left and top using division or multiply with scale factor.
The good way is using
canvas.setZoom(scale);
This will save a lot of headaches to you.
$(function () {
scale = 0.5;
canvas1 = new fabric.Canvas('c1');
canvas1.setDimensions({
"width": canvas.getWidth() * scale,
"height": canvas.getHeight() * scale
})
var json = localStorage.getItem('save');
canvas1.loadFromJSON(json, function () {
canvas1.renderAll();
});
canvas1.setZoom(scale);
canvas1.renderAll();
});
chek updated fiddle
https://jsfiddle.net/asturur/Lep9w01L/11/

jspdf and addHTML / blurry font

I generate pdf file from a HTML-page via jspdf plugin addHTML.
It works but the rendered text / font is really blurry, the original HTML page is not. Rendered images are fine, only text is the problem (see attached images).
original_image: http://111900.test-my-website.de/stackoverflow/orig.jpg
blurry_image: http://111900.test-my-website.de/stackoverflow/blurry.jpg
I read all google results the last three days - maybe I am the only person in the world I have exact this problem?!?! :/
I added the following scripts in my code:
spdf.js
jspdf.plugin.from_html.js
jspdf.plugin.split_text_to_size.js
jspdf.plugin.standard_fonts_metrics.js
pdf generation code:
pdf.addHTML(document.getElementById("container"),10,15,function() {
var string = pdf.save(filename);
});
Is there a quality option in jspdf I missed?
How can I render the font?
Thanks for reply,
Thomas
I found that when creating a PDF and the text was blurred when using addHtml this was because of the width of the web page. Try using it with the browser not maximised as a test.
My solution was to add some styles to adjust the width before calling addHTML with a width parameter that matches the styles I added. I then remove the additional styles in the function that runs after addHTML.
I had the same problem and I resolved it.
Actually, the main issue here is to specify the 'dpi' to avoid having a blurred image. In addition to that, try to avoid any 'smoothening' features beacuse it may make it worse. I have taken a look around the API and other discussion about it and I came back with the following solution:
1- update your version of html2canvas : many blurring issues have been fixed after the 1.0.0-alpha release.
2- use the following properties :
const context = canvas.getContext('2d');
context.scale(2, 2);
context['dpi'] = 144;
context['imageSmoothingEnabled'] = false;
context['mozImageSmoothingEnabled'] = false;
context['oImageSmoothingEnabled'] = false;
context['webkitImageSmoothingEnabled'] = false;
context['msImageSmoothingEnabled'] = false;

Resources