Meet us at PRINT 19. Chicago, IL. Oct. 3 - 5.
This documentation is for the old version. Go to the latest Graphics Mill docs

Remote Scripting Approach (Web Controls)

Web controls of the Graphics Mill for .NET provides very convenient and powerful feature - possibility to invoke server code directly from the JavaScript. It enables you to run this code without reloading of the page (this approach is also known as AJAX). Undoubtedly, it greatly reduces your efforts of creating interactive and user-friendly web interface.

Before we drill into the code example, let's examine the basics of the remote scripting mechanism of the Graphics Mill for .NET. It consists of two parts: server method and JavaScript code.

  1. The server code you are going to invoke from the JavaScript should satisfy the following conditions:
  2. At the client side you should use the methods of the JavaScript class BitmapViewer, in particular:
    • invokeRemoteMethod(name,args) - runs the remote method with specified name. Arguments are retrieved in the array. The first element of the array is passed into the first argument, the second element - into the second one, etc. Number of array items should be the same as a number of arguments.
    • addStatusChanged(handler,destination) - attaches the event handler which enables you to determine when the bitmap status changed (and therefore determine when the operation completes).
    • getStatus() - returns the status of the bitmap. When it equals to "Ready", it means that the bitmap is ready to be used. In particular, you can use it in the StatusChanged event handler to determine when the operation completes.
    • removeStatusChanged(handler,destination) - detaches the event handler of the bitmap status change event.
    • getReturnValue() - retrieves the value returned from the remote method (if any).
    • getExceptionName() - if the remote method fails, it returns the exception name.
    • getExceptionDescription() - if the remote method fails, it returns the exception description.

Now let's see a code example. For example, we want to put a vignette with adjustable width at the image. To do it, we add a server method AddVignette, mark it with the RemoteScriptingMethodAttribute attribute, and call it when the button Add Vignette is clicked. The vignette width is selected from the drop down list and sent to server.

ASP.NET Visual Basic
<%@ Page language="VB" AutoEventWireup="true"%>
<%@ Register TagPrefix="aur" Namespace="Aurigma.GraphicsMill.WebControls" 
	Assembly="Aurigma.GraphicsMill.WebControls" %>
<script runat="server" language="VB">
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
	If Not Page.IsPostBack Then
		BitmapViewer1.Bitmap.Load(Server.MapPath("SourceImages/Mountain.jpg"))
	End If
End Sub

<Aurigma.GraphicsMill.WebControls.RemoteScriptingMethod> _
Public Sub AddVignette(width As Integer)
	BitmapViewer1.Bitmap.Transforms.Buttonize(width, _
		Aurigma.GraphicsMill.Transforms.FadeType.Nonlinear, _
		Aurigma.GraphicsMill.Transforms.Direction.UpLeft, _
		Aurigma.GraphicsMill.RgbColor.Black, _
		Aurigma.GraphicsMill.RgbColor.Black)
End Sub
</script>
<html>
	<head>
		<title>Remote Scripting</title>
		<script language="javascript">
function AddVignette_click(){
	var selectBorderWidth = document.getElementById("SelectBorderWidth");
	var width = selectBorderWidth.options[selectBorderWidth.selectedIndex].value * 1;

	var bitmapViewer1 = document.getElementById("<%=BitmapViewer1.ClientID%>");	

	var params=new Array();
	params.push(width)
	
	bitmapViewer1.invokeRemoteMethod("AddVignette", params);
}
		</script>
	</head>
	<body>
		<form runat="server" ID="Form1">
			Border width:
			<select id="SelectBorderWidth">
				<option>30</option>
				<option selected>50</option>
				<option>80</option>
			</select>
			<input id="InputAddVignette" type="button" value="Add Vignette" onclick="AddVignette_click();">
			<br>
			<br>
			<aur:BitmapViewer id="BitmapViewer1" runat="server" Width="400px" Height="300px"></aur:BitmapViewer>
		</form>
	</body>
</html>
ASP.NET C#
<%@ Page language="C#" AutoEventWireup="true" %>
<%@ Register TagPrefix="aur" Namespace="Aurigma.GraphicsMill.WebControls" 
	Assembly="Aurigma.GraphicsMill.WebControls" %>
<script runat="server" language="C#">
private void Page_Load(object sender, System.EventArgs e)
{
	if (!Page.IsPostBack)
	{
		BitmapViewer1.Bitmap.Load(Server.MapPath("SourceImages/Mountain.jpg"));
	}
}

[Aurigma.GraphicsMill.WebControls.RemoteScriptingMethod]
public void AddVignette(int width)
{
	BitmapViewer1.Bitmap.Transforms.Buttonize(width,
		Aurigma.GraphicsMill.Transforms.FadeType.Nonlinear,
		Aurigma.GraphicsMill.Transforms.Direction.UpLeft,
		Aurigma.GraphicsMill.RgbColor.Black,
		Aurigma.GraphicsMill.RgbColor.Black);
}
</script>
<html>
	<head>
		<title>Remote Scripting</title>
		<script language="javascript">
function AddVignette_click(){
	var selectBorderWidth = document.getElementById("SelectBorderWidth");
	var width = selectBorderWidth.options[selectBorderWidth.selectedIndex].value * 1;

	var bitmapViewer1 = document.getElementById("<%=BitmapViewer1.ClientID%>");	

	var params=new Array();
	params.push(width)
	
	bitmapViewer1.invokeRemoteMethod("AddVignette", params);
}
		</script>
	</head>
	<body>
		<form runat="server" ID="Form1">
			Border width:
			<select id="SelectBorderWidth">
				<option>30</option>
				<option selected>50</option>
				<option>80</option>
			</select>
			<input id="InputAddVignette" type="button" value="Add Vignette" 
				onclick="AddVignette_click();">
			<br>
			<br>
			<aur:BitmapViewer id="BitmapViewer1" runat="server" 
				Width="400px" Height="300px">
			</aur:BitmapViewer>
		</form>
	</body>
</html>

Now let's examine a bit more complicated code example. It demonstrates how to handle exceptions occurred at the remote method. Also, this code demonstrates how to work with return values. This code builds a histogram of the image and sends the median value of this histogram to the client.

ASP.NET Visual Basic
<%@ Page language="VB" AutoEventWireup="true"%>
<%@ Register TagPrefix="aur" Namespace="Aurigma.GraphicsMill.WebControls" 
	Assembly="Aurigma.GraphicsMill.WebControls" %>
<script runat="server" language="VB">
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
	If Not Page.IsPostBack Then
		BitmapViewer1.Bitmap.Load(Server.MapPath("SourceImages/Mountain.jpg"))
	End If
End Sub

<Aurigma.GraphicsMill.WebControls.RemoteScriptingMethod> _
Public Function GetStatistics() As Single
	Return BitmapViewer1.Bitmap.Statistics.GetLuminosityHistogram().Median
End Function
</script>
<html>
	<head>
		<title>Remote Scripting</title>
		<script language="javascript">
function GetStatistics_click(){
	var bitmapViewer1 = document.getElementById("<%=BitmapViewer1.ClientID%>");	
	bitmapViewer1.invokeRemoteMethod("GetStatistics", null);
	
	//Attach event handler on call completion
	bitmapViewer1.addStatusChanged(bitmapViewer1_addStatusChanged, this);
}

function bitmapViewer1_addStatusChanged(){
	var bitmapViewer1 = document.getElementById("<%=BitmapViewer1.ClientID%>");	

	//Detach event handler on call completion
	bitmapViewer1.removeStatusChanged(bitmapViewer1_addStatusChanged, this);	

	//Check whether exception occured
	if (bitmapViewer1.getExceptionName() == ""){
		alert("Median of image histogram is " + bitmapViewer1.getReturnValue() + ".");
	}
	else{
		alert("Following exception occured during calling remote method:\n\r" +
			bitmapViewer1.getExceptionName() + "\n\r" + bitmapViewer1.getExceptionDescription());
	}
}
		</script>
	</head>
	<body>
		<form runat="server" ID="Form1">
			<input id="InputGetStatistics" type="button" value="Get Statistics" onclick="GetStatistics_click();">
			<br>
			<br>
			<aur:BitmapViewer id="BitmapViewer1" runat="server" Width="400px" Height="300px"></aur:BitmapViewer>
		</form>
	</body>
</html>
ASP.NET C#
<%@ Page language="C#" AutoEventWireup="true" %>
<%@ Register TagPrefix="aur" Namespace="Aurigma.GraphicsMill.WebControls" 
	Assembly="Aurigma.GraphicsMill.WebControls" %>
<script runat="server" language="C#">
private void Page_Load(object sender, System.EventArgs e)
{
	if (!Page.IsPostBack)
	{
		BitmapViewer1.Bitmap.Load(Server.MapPath("SourceImages/Mountain.jpg"));
	}
}

[Aurigma.GraphicsMill.WebControls.RemoteScriptingMethod]
public float GetStatistics()
{
	return BitmapViewer1.Bitmap.Statistics.GetLuminosityHistogram().Median;
}
</script>
<html>
	<head>
		<title>Remote Scripting</title>
		<script language="javascript">
function GetStatistics_click(){
	var bitmapViewer1 = document.getElementById("<%=BitmapViewer1.ClientID%>");	
	bitmapViewer1.invokeRemoteMethod("GetStatistics", null);
	
	//Attach event handler on call completion
	bitmapViewer1.addStatusChanged(bitmapViewer1_addStatusChanged, this);
}

function bitmapViewer1_addStatusChanged(){
	var bitmapViewer1 = document.getElementById("<%=BitmapViewer1.ClientID%>");	

	//Detach event handler on call completion
	bitmapViewer1.removeStatusChanged(bitmapViewer1_addStatusChanged, this);	

	//Check whether exception occured
	if (bitmapViewer1.getExceptionName() == ""){
		alert("Median of image histogram is " + bitmapViewer1.getReturnValue() + ".");
	}
	else{
		alert("Following exception occured during calling remote method:\n\r" +
			bitmapViewer1.getExceptionName() + "\n\r" + bitmapViewer1.getExceptionDescription());
	}
}
		</script>
	</head>
	<body>
		<form runat="server" ID="Form1">		
			<input id="InputGetStatistics" type="button" value="Get Statistics" 
				onclick="GetStatistics_click();">
			<br>
			<br>
			<aur:BitmapViewer id="BitmapViewer1" runat="server" 
				Width="400px" Height="300px">
			</aur:BitmapViewer>
		</form>
	</body>
</html>

You see, Graphics Mill for .NET provides elegant and easy-to-use powerful remote scripting mechanism. You can use it to run almost any server code. However in the conclusion we would like to warn you to write server code carefully. We highly recommend you not to put a RemoteScriptingMethodAttribute attribute at the methods which are not actually necessary to be run. Also, if the performance of the method depends on the arguments, it is strongly recommended to check such argument to avoid malicious attacks. For example, if you create new bitmap in this method and pass it dimensions from the JavaScript, you must check them and do not run the method if the dimensions are too wild. You can find more guidelines for creating the reliable server code in the topic Scalability and Reliability of Web Applications.