Occurs when a picture object has been finished loading its source image.
Object.defineProperty(AnnRenderingEngine.prototype,'loadPicture',get: function(),set: function(value))
loadPicture: LeadEvent; AnnLoadPictureEventArgs
In the LEADTOOLS Annotation framework, the source image in picture objects is not loaded till render time. For example, when you first render an annotation object that contains a picture, such as the AnnHotspotObject or AnnPointObject, the framework will load the image in AnnPicture.Source in the background. While the image is loading, the framework will use a placeholder rectangle to render the object position and size. When the image is fully loaded, the framework will fire the LoadPicture event and renders the new image instead of the placeholder.
LoadingPictureStroke and LoadingPictureFill are the objects to use for stroking and filling the placeholder rectangle. Default values are a white stroke on a black background.
The LoadPicture event contains data about the picture that finished loading such as the Picture object itself and the owner AnnObject. Also, the event data contains the Error property that will be populated if an error occurred.
Loading an image in the background is an efficient and easy way to start drawing an annotation object without waiting for all the resources to be available in the browser. This is especially true if the object contains a picture with a source URL on a server machine and takes a few seconds to download.
This example will create a picture from a resource in a remote server and use it with a hotspot annotation object. It will then uses automation to start drawing the object as the image is being loaded.
import { EngineHelper } from "../utilities/EngineHelper";export class AnnRenderingEngine_LoadPicture {constructor() {const helper = new EngineHelper();helper.run(this.loadPicture);}loadPicture = (automation: lt.Annotations.Automation.AnnAutomation) => {// get the current rendering enginelet renderingEngine: lt.Annotations.Engine.AnnRenderingEngine = automation.automationControl.renderingEngine;// Change the default loading object placeholder to be a green border with semi-transparent backgroundconst stroke: lt.Annotations.Engine.AnnStroke = lt.Annotations.Engine.AnnStroke.create(lt.Annotations.Engine.AnnSolidColorBrush.create("green"),lt.LeadLengthD.create(1));const fill: lt.Annotations.Engine.AnnBrush = lt.Annotations.Engine.AnnSolidColorBrush.create("rgba(0, 0, 0, 0.5)");renderingEngine.loadingPictureStroke = stroke;renderingEngine.loadingPictureFill = fill;// Hook to the LoadPicture eventrenderingEngine.add_loadPicture((sender, e) => {// e is AnnLoadPictureEventArgs// Check if an error occurredif (e.error != null) {// Show info about the errorlet str = e.error.message;str += "\nSource: " + e.picture.source;str += "\nOwner object: " + e.annObject.friendlyName;alert(str);}// Re-render the container after picture get loadedautomation.invalidate(lt.LeadRectD.empty);});// Create a new AnnHotspotObject with a picture from a remote serverconst inch: number = 720;const hotspot: lt.Annotations.Engine.AnnHotspotObject = new lt.Annotations.Engine.AnnHotspotObject();// Add the object at location 1,1 inch with size 4,2 incheshotspot.rect = lt.LeadRectD.create(1 * inch, 1 * inch, 4 * inch, 2 * inch);// Set its pictureconst picture: lt.Annotations.Engine.AnnPicture = new lt.Annotations.Engine.AnnPicture("");picture.source = "https://www.leadtools.com/images/page_graphics/leadlogo.png";//NOTE: CORS can cause toDataUrl to fail// Alternatively, use a local resource//picture.source = "Resources/leadlogo.png";hotspot.picture = picture;// Add it to the containerconst container: lt.Annotations.Engine.AnnContainer = automation.container;container.children.add(hotspot);// Render the containerautomation.invalidate(lt.LeadRectD.empty);}}
export class EngineHelper {// Automation objectprotected _automation: lt.Annotations.Automation.AnnAutomation = null;// Image viewerprotected _viewer: lt.Controls.ImageViewer = null;constructor() {// Set the LEADTOOLS license. Replace this with your actual license filelt.RasterSupport.setLicenseUri("https://demo.leadtools.com/licenses/js/LEADTOOLSEVAL.txt", "EVAL", null);}public run(callback?: (automation: lt.Annotations.Automation.AnnAutomation, viewer: lt.Controls.ImageViewer) => void): void {// Create the viewerconst imageViewerDiv = document.getElementById("imageViewerDiv");const createOptions: lt.Controls.ImageViewerCreateOptions = new lt.Controls.ImageViewerCreateOptions(imageViewerDiv);const viewer: lt.Controls.ImageViewer = new lt.Controls.ImageViewer(createOptions);viewer.autoCreateCanvas = true;this._viewer = viewer;// PanZoom interactive modeconst panZoom: lt.Controls.ImageViewerPanZoomInteractiveMode = new lt.Controls.ImageViewerPanZoomInteractiveMode();// Create an instance of the Automation control object that works with LEADTOOLS ImageViewerconst imageViewerAutomationControl: lt.Demos.Annotations.ImageViewerAutomationControl = new lt.Demos.Annotations.ImageViewerAutomationControl();// Attach our image viewerimageViewerAutomationControl.imageViewer = viewer;// Set the image viewer interactive modeconst automationInteractiveMode: lt.Demos.Annotations.AutomationInteractiveMode = new lt.Demos.Annotations.AutomationInteractiveMode();automationInteractiveMode.automationControl = imageViewerAutomationControl;// Set the image URLviewer.imageUrl = "http://demo.leadtools.com/images/png/pngimage.png";// Create and set up the automation manager using the HTML5 rendering engineconst renderingEngine: lt.Annotations.Rendering.AnnHtml5RenderingEngine = new lt.Annotations.Rendering.AnnHtml5RenderingEngine();const manager: lt.Annotations.Automation.AnnAutomationManager = lt.Annotations.Automation.AnnAutomationManager.create(renderingEngine);// Create default automation objectsmanager.createDefaultObjects();// Add the objects to the objects select elementconst currentObjectIdSelect = document.getElementById("currentObjectIdSelect") as HTMLSelectElement;// Add the PanZoom optioncurrentObjectIdSelect.options[currentObjectIdSelect.options.length] = new Option("Pan/Zoom", lt.Annotations.Engine.AnnObject.none.toString());const automationObjCount: number = manager.objects.count;for (let i = 0; i < automationObjCount; i++) {// Get the objectconst automationObj: lt.Annotations.Automation.AnnAutomationObject = manager.objects.item(i);// Add its name to the select elementconst name: string = automationObj.name;const id: string = automationObj.id.toString();currentObjectIdSelect.options[currentObjectIdSelect.options.length] = new Option(name, id);}// Hook to its change eventcurrentObjectIdSelect.addEventListener("change", () => {// Get the object IDconst id: number = parseInt(currentObjectIdSelect.options[currentObjectIdSelect.selectedIndex].value);// Set it as the current object in the managermanager.currentObjectId = id;// If this is the "Pan/Zoom" option, then back to pan zoom, otherwise, set our automation controlif (id == lt.Annotations.Engine.AnnObject.none) {viewer.defaultInteractiveMode = panZoom;}else {viewer.defaultInteractiveMode = automationInteractiveMode;}});// When the current object ID changes, we need to update our selectmanager.add_currentObjectIdChanged((sender, e) => {const currentObjectId: number = manager.currentObjectId;for (let i = 0; i < currentObjectIdSelect.options.length; i++) {const id: number = parseInt(currentObjectIdSelect.options[i].value);if (id === currentObjectId) {currentObjectIdSelect.selectedIndex = i;break;}}});// Pan zoom by defaultviewer.defaultInteractiveMode = panZoom;// set up the automation (will create the container as well)const automation: lt.Annotations.Automation.AnnAutomation = new lt.Annotations.Automation.AnnAutomation(manager, imageViewerAutomationControl);this._automation = automation;// Add handler to update the container size when the image size changesviewer.itemChanged.add((sender, e) => {const container: lt.Annotations.Engine.AnnContainer = automation.container;container.size = container.mapper.sizeToContainerCoordinates(viewer.imageSize);//Create new canvas data provider for the new imageconst canvasDataProvider: lt.Demos.Annotations.CanvasDataProvider = new lt.Demos.Annotations.CanvasDataProvider(viewer.activeItem.canvas);imageViewerAutomationControl.automationDataProvider = canvasDataProvider;});// set up this automation as the active onethis._automation.active = true;const exampleButton = document.getElementById("exampleButton");exampleButton.onclick = () => {if(callback)callback(this._automation, this._viewer);}}}
import { EngineHelper } from "../utilities/EngineHelper";export class AnnRenderingEngine_LoadPicture {constructor() {const helper = new EngineHelper();helper.run(this.loadPicture);}loadPicture = (automation) => {// get the current rendering enginelet renderingEngine = automation.automationControl.renderingEngine;// Change the default loading object placeholder to be a green border with semi-transparent backgroundconst stroke = lt.Annotations.Engine.AnnStroke.create(lt.Annotations.Engine.AnnSolidColorBrush.create("green"),lt.LeadLengthD.create(1));const fill = lt.Annotations.Engine.AnnSolidColorBrush.create("rgba(0, 0, 0, 0.5)");renderingEngine.loadingPictureStroke = stroke;renderingEngine.loadingPictureFill = fill;// Hook to the LoadPicture eventrenderingEngine.add_loadPicture((sender, e) => {// e is AnnLoadPictureEventArgs// Check if an error occurredif (e.error != null) {// Show info about the errorlet str = e.error.message;str += "\nSource: " + e.picture.source;str += "\nOwner object: " + e.annObject.friendlyName;alert(str);}// Re-render the container after picture get loadedautomation.invalidate(lt.LeadRectD.empty);});// Create a new AnnHotspotObject with a picture from a remote serverconst inch = 720;const hotspot = new lt.Annotations.Engine.AnnHotspotObject();// Add the object at location 1,1 inch with size 4,2 incheshotspot.rect = lt.LeadRectD.create(1 * inch, 1 * inch, 4 * inch, 2 * inch);// Set its pictureconst picture = new lt.Annotations.Engine.AnnPicture("");picture.source = "https://www.leadtools.com/images/page_graphics/leadlogo.png";//NOTE: CORS can cause toDataUrl to fail// Alternatively, use a local resource//picture.source = "Resources/leadlogo.png";hotspot.picture = picture;// Add it to the containerconst container = automation.container;container.children.add(hotspot);// Render the containerautomation.invalidate(lt.LeadRectD.empty);}}
export class EngineHelper {// Automation object_automation = null;// Image viewer_viewer = null;constructor() {// Set the LEADTOOLS license. Replace this with your actual license filelt.RasterSupport.setLicenseUri("https://demo.leadtools.com/licenses/js/LEADTOOLSEVAL.txt", "EVAL", null);}run(callback) {// Create the viewerconst imageViewerDiv = document.getElementById("imageViewerDiv");const createOptions = new lt.Controls.ImageViewerCreateOptions(imageViewerDiv);const viewer = new lt.Controls.ImageViewer(createOptions);viewer.autoCreateCanvas = true;this._viewer = viewer;// PanZoom interactive modeconst panZoom = new lt.Controls.ImageViewerPanZoomInteractiveMode();// Create an instance of the Automation control object that works with LEADTOOLS ImageViewerconst imageViewerAutomationControl = new lt.Demos.Annotations.ImageViewerAutomationControl();// Attach our image viewerimageViewerAutomationControl.imageViewer = viewer;// Set the image viewer interactive modeconst automationInteractiveMode = new lt.Demos.Annotations.AutomationInteractiveMode();automationInteractiveMode.automationControl = imageViewerAutomationControl;// Set the image URLviewer.imageUrl = "http://demo.leadtools.com/images/png/pngimage.png";// Create and set up the automation manager using the HTML5 rendering engineconst renderingEngine = new lt.Annotations.Rendering.AnnHtml5RenderingEngine();const manager = lt.Annotations.Automation.AnnAutomationManager.create(renderingEngine);// Create default automation objectsmanager.createDefaultObjects();// Add the objects to the objects select elementconst currentObjectIdSelect = document.getElementById("currentObjectIdSelect");// Add the PanZoom optioncurrentObjectIdSelect.options[currentObjectIdSelect.options.length] = new Option("Pan/Zoom", lt.Annotations.Engine.AnnObject.none.toString());const automationObjCount = manager.objects.count;for (let i = 0; i < automationObjCount; i++) {// Get the objectconst automationObj = manager.objects.item(i);// Add its name to the select elementconst name = automationObj.name;const id = automationObj.id.toString();currentObjectIdSelect.options[currentObjectIdSelect.options.length] = new Option(name, id);}// Hook to its change eventcurrentObjectIdSelect.addEventListener("change", () => {// Get the object IDconst id = parseInt(currentObjectIdSelect.options[currentObjectIdSelect.selectedIndex].value);// Set it as the current object in the managermanager.currentObjectId = id;// If this is the "Pan/Zoom" option, then back to pan zoom, otherwise, set our automation controlif (id == lt.Annotations.Engine.AnnObject.none) {viewer.defaultInteractiveMode = panZoom;}else {viewer.defaultInteractiveMode = automationInteractiveMode;}});// When the current object ID changes, we need to update our selectmanager.add_currentObjectIdChanged((sender, e) => {const currentObjectId = manager.currentObjectId;for (let i = 0; i < currentObjectIdSelect.options.length; i++) {const id = parseInt(currentObjectIdSelect.options[i].value);if (id === currentObjectId) {currentObjectIdSelect.selectedIndex = i;break;}}});// Pan zoom by defaultviewer.defaultInteractiveMode = panZoom;// set up the automation (will create the container as well)const automation = new lt.Annotations.Automation.AnnAutomation(manager, imageViewerAutomationControl);this._automation = automation;// Add handler to update the container size when the image size changesviewer.itemChanged.add((sender, e) => {const container = automation.container;container.size = container.mapper.sizeToContainerCoordinates(viewer.imageSize);//Create new canvas data provider for the new imageconst canvasDataProvider = new lt.Demos.Annotations.CanvasDataProvider(viewer.activeItem.canvas);imageViewerAutomationControl.automationDataProvider = canvasDataProvider;});// set up this automation as the active onethis._automation.active = true;const exampleButton = document.getElementById("exampleButton");exampleButton.onclick = () => {if(callback)callback(this._automation, this._viewer);}}}
<!doctype html><html lang="en"><title>AnnRenderingEngine Example | LoadPicture</title><head><script src="https://code.jquery.com/jquery-2.2.4.min.js"integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script><script src="../LT/Leadtools.js"></script><script src="../LT/Leadtools.Controls.js"></script><script src="../LT/Leadtools.Annotations.Engine.js"></script><script src="../LT/Leadtools.Annotations.Designers.js"></script><script src="../LT/Leadtools.Annotations.Rendering.Javascript.js"></script><script src="../LT/Leadtools.Annotations.Automation.js"></script><script src="../LT/Leadtools.Annotations.BatesStamp.js"></script><script src="../LT/Leadtools.Demos.js"></script><script src="../LT/Leadtools.Demos.Annotations.js"></script><style>#imageViewerDiv {border: 1px solid #000000;width: 800px;height: 800px;background-color: #7F7F7F;}</style><!-- All demo files are bundled and appended to the window --><script src="../../bundle.js" type="text/javascript"></script></head><body><p>Either Pan/Zoom or Annotations mode. In annotations mode, draw new objects or edit them.</p><div><select id="currentObjectIdSelect"></select></div><div><input type="button" id="exampleButton" value="Example" /><label id="exampleLabel" /></div><div id="imageViewerDiv" /></body><script>window.onload = () => new window.examples.AnnRenderingEngine.LoadPicture();</script></html>
| Parameter | Type | Description | 
|---|---|---|
| sender | var | The source of the event. | 
| e | AnnLoadPictureEventArgs | The event data. | 
Help Collections
Raster .NET | C API | C++ Class Library | HTML5 JavaScript
Document .NET | C API | C++ Class Library | HTML5 JavaScript
Medical .NET | C API | C++ Class Library | HTML5 JavaScript
Medical Web Viewer .NET
Multimedia
Direct Show .NET | C API | Filters
Media Foundation .NET | C API | Transforms
Supported Platforms
.NET, Java, Android, and iOS/macOS Assemblies
Imaging, Medical, and Document
C API/C++ Class Libraries
Imaging, Medical, and Document
HTML5 JavaScript Libraries
Imaging, Medical, and Document
