Programming Guide   >   Viewing   >   Miscellaneous Topics

Image and SVG Generation

Overview – Image Creation

The HOOPS Web Viewer supports the ability to take a snapshot image of the current HOOPS Web Viewer Canvas. The result is an HTMLImageElement which can be displayed directly in in the current browser, or the image data can be extracted and sent back to the web-server.

Example: Creating and Displaying a Snapshot Image

To create a snapshot image, call the function takeSnapshot() which can be found in the Communicator.WebViewer class. The takeSnapshot() function takes an optional Communicator.SnapshotConfig which can be used to control the size of the resultant image. The return value of takeSnapshot() is a Promise that resolves to an HTMLImageElement containing the created image.

The full HTML and Javascript for this example can be viewed in the Communicator package in the examples folder: web_viewer/examples/simple_snapshot.html

This simple example first creates a snapshot image, then adds the newly created image into the same web-page that contains the HOOPS Web Viewer Canvas. First, you'll need an HTML page that creates and starts the HOOPS Web Viewer. For the purpose of this example, it is assumed the HOOPS Web Viewer Canvas is sized to 640x480 pixels. Next, add an empty HTML <div> tag as the last tag within the <body> section of the page, like this:

<div id="snapshots"></div>

Next, add a button to the html page and have it call the following function which will generate a snapshot image and display the result. This function first creates the image, then upon it's completion, appends it to the content of our <div> tag. Note that the image is created much smaller than the source canvas by passing the width/height as configuration parameters.

function createSnapshot(viewer) {
viewer.takeSnapshot({ width: 160, height: 120 }).then(function (image) {
document.getElementById("snapshots").appendChild(image);
});
}

Snapshot Configuration

The following fields are available to set within the Communicator.SnapshotConfig class.

width: number

Specifies the width of the resulting snapshot image. A value of 0 indicates the canvas width should be used. The default value is 0.

height: number

Specifies the height of the resulting snapshot image. A value of 0 indicates the canvas height should be used. The default value is 0.

Extracting the Image Data

To extract the image data from the return image element, you can use a temporary HTML Canvas object which acts as an offscreen buffer. First you create the canvas object, then draw the image to it, and finally extract the result from the canvas. The following example code shows how extract the image data as base64 encoded string:

viewer.takeSnapshot().then(function(image) {
var canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(image, 0, 0);
var base64Encoded = canvas.toDataURL("image/png");
console.log(base64Encoded);
});

The resultant console output will look something like:

data:image/png;base64,iVBORw0Kggo…

You can also use the canvas.toBlob() function to extract the image data as blob, which would be suitable for sending the image back to a server in binary form. For more information on sending blobs, see https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data

Overview - SVG Creation

The HOOPS Web Viewer has the ability to create a two-dimensional Scalable Vector Graphics (SVG) representation of the currently displayed scene. The resultant SVG will contain a series of polygons and polylines that when rendered, will look similar to the original three-dimensional view.

SVG Features

An important feature of an SVG is its ability to render with high fidelity at varying zoom levels. This is an advantage over bitmapped images, which tend to show pixelated artifacts at high zoom levels.

SVG Limitations

The SVG representations created by the HOOPS Web Viewer have a few limitations. First, there is no shading or lighting in the SVG. Thus, faces of the model will be flat shaded with uniform color based on the color defined for that face. Any textures in the model are ignored.

Another limitation with SVG creation is processing time. Generating an SVG from a three-dimensional view is computationally expensive and does not use the GPU like typical rendering solutions. Very small models may take a few seconds to export, while large models can take minutes.

Example: Creating and Displaying an SVG

To create an SVG, call the function exportToSvg() which can be found in the Communicator.WebViewer class. The exportToSvg() takes an optional Communicator.SvgConfig which can be used to control certain aspects of the resultant SVG. The return value of exportToSvg() is a Promise that resolves to a string containing the created SVG.

The full HTML and Javascript for this example can be viewed in the Communicator package in the examples folder: web_viewer/examples/svg_display.html

This simple example first creates an SVG, then renders the result in the same web-page that contains the HOOPS Web Viewer. First, you'll need an HTML page that creates and starts the HOOPS Web Viewer. For the purpose of this example, it is assumed the HOOPS Web Viewer Canvas is sized 640x480 pixels. Next, add an empty HTML <div> tag as the last tag within the <body> section of the page, like this:

<div id="display-svg" style="width: 640px; height: 480px"></div>

Next, add a button to the html page and have it call the following function which will generate an SVG and display the result. This function first creates the SVG, then upon its completion, sets the content of our <div> tag to the created SVG string. This works because the SVG creation returns an XML string with a root tag of <svg> that can be directly interpreted and rendered by modern browsers.

function createSvg(viewer) {
viewer.exportToSvg({ svgXmlPrologEnabled: false }).then(function (svgString) {
document.getElementById("display-svg").innerHTML = svgString;
});
}

If you'd like to export to a new browser tab, use the following code (requires Pop-Ups to be enabled in the browser):

let mainWindow, svgWindow = null;
mainWindow = window;
svgWindow = window.open("", "SVG");
svgWindow.document.title = "Creating SVG";
myViewer.exportToSvg().then((svgString) => {
svgWindow.document.open();
svgWindow.document.write(svgString);
svgWindow.document.title = "SVG";
svgWindow.document.close();
});

As in the examples above, the exportToSvg() function can be called with no arguments, or you can pass it an SvgConfig object that contains various settings related to output, styling, etc. For example:

var myConfig = new Communicator.SvgConfig();
myConfig.svgBackgroundCssColor = "#ff00ff";
myViewer.exportToSvg(myConfig).then(console.log);

Using the Results

The format of SVG is XML, and therefore the string returned by exportToSvg() will be a well-formed XML string. A typical XML document will begin with a prolog string like:

<?xml version='1.0' encoding='UTF-8' standalone='no'?>

Depending on how you intend to use the results, you can specify if this prolog is present. If the result is going to be saved off as a standalone XML file with an ".svg" suffix, then the prolog should be present. If the result is going to be directly rendered in a page like the previous example, then the prolog should be suppressed. The default configuration will include the prolog but it can be suppressed via the configuration parameter.

If you would like the SVG string to be used as a standalone file, you will need to extract from the web-page. A simplistic way to do this would be to simply display the string, say in a simple pop-up, and allow the user to copy-paste it. A more sophisticated approach would be to send it back to the web-server for storage. This can be done with the XMLHttpRequest class, which is detailed here.

SVG Configuration

The following fields are available within the Communicator.SvgConfig class:

Field Description
linesClipProximityToPlane: number For line clipping, this factor determines how close a line can get to a triangle without getting clipped. Larger values will help small sections that shouldn't get clipped, but larger values may also allow hidden line sections to poke through. Z values are normalized to -32767 to 32767, so this value is relative to that scale. (default: 5.5)
linesClipZNudgeFactor: number For line clipping, this value will be used to adjust line segment endpoints, bringing closer to the camera for positive values. This is helpful for z-fighting causing small sections of lines to be unintentionally clipped. Z values are normalized to -32767 to 32767, so this value is relative to that scale. (default: 5.5)
linesCssColor: string CSS compliant color string used to draw lines (default: "#000000")
linesDrawModelLinesEnabled: boolean Determines if the model lines will be included in the SVG output (default: true)
linesStrokeWidth: number Determines the output SVG line width for all lines in the model. This is relative to the SVG viewBox settings of -32767 to +32767 in both X and Y directions. (default: 20.0)
logDiagnostics: boolean Enables diagnostics logging. If running in-browser, this will go to the developer console (default: false)
logProgress: boolean Enables progress logging. If running in-browser, this will go to the developer console (default: false)
polygonsForceDrawCssColor: string If set to a non-empty CSS string value, forces all polygons to be drawn as this color. Example, to force all polygons to be white, use PolygonsForceDrawColor="#ffffff"(default: "")
silhouettesEnabled: boolean Determines if silhouette lines will be drawn for the model (default: true)
svgBackgroundCssColor: string If non-empty, an SVG element will be at the root with the given background color. (default: "")
svgXmlPrologEnabled: boolean If true, the standard XML prolog will be included in the output SVG (default: true)