Paging Through Multipage Tiffs using RemoteInvoke
We've been getting quite a few questions in reguard to AJAX style paging through multi-page Tiff files. This topic shows how simple this task is using our WebImageViewer control.
First, drop a WebImageViewer control on the form, we'll call this one WebImageViewer1 for simplicity. If you haven't used this control before, you will need to setup up the file cache covered in this knowledgebase article: http://www.atalasoft.com/kb/article.aspx?id=10062&cNode=5M3M7A
Next, drop a couple regular HTML buttons ('Button' under the HTML section of the toolbox in Visual Studio) on the form, and name them Previous and Next. Add an onclick attribute to these buttons that uses a JavaScript function that we'll make in the next step... it should look something like this:
<input type="button" value="Previous" onclick="Page(-1);">
<input type="button" value="Next" onclick="Page(1);">
Ok, we need to know how many pages are in this document, and what url to open. The simplest way to get the page information is by using GetImageInfo when we load the document. In this example I used a couple hidden input tags ('Hidden' under the HTML section of the toolbox in Visual Studio) called Hidden_Pages and Hidden_Url. To access it on the server, we need to add runat="server" to the tag, Visual studio lets you do this by right clicking on it in the Design View, and select 'Run as Server Control'. For simplicity, we're going to load the image on page load, and set the hidden values:
private void Page_Load(object sender, System.EventArgs e)
{
if (!Page.IsPostBack)
{
string url = "myMultipageTiff.tiff";
this.Hidden_Pages.Value = RegisteredDecoders.GetImageInfo(Page.MapPath(url)).FrameCount;
this.Hidden_Url.Value = url;
this.WebImageViewer1.OpenUrl(url);
}
}
In order for use to do this without posting back we First need to make a RemoteInvokable method and a JavaScript function that will open a particular frame of the image:
Server Side:
[RemoteInvokable]
public void Remote_LoadFrame(string url, int frame)
{
this.WebImageViewer1.OpenUrl(url, frame);
}
Client Side:
function LoadFrame(frameIndex){
WebImageViewer1.RemoteInvoke('Remote_LoadFrame', new Array(url, frameIndex));
}
Next we will set up the client side code for when the page loads, atalaInitClientScript allows us to do this easily:
var numPages;
var currentPage = 0;
var url;
atalaInitClientScript("OnPageLoad();");
function OnPageLoad(){
numPages = parseInt(document.getElementById("Hidden_Pages").value);
url = document.getElementById("Hidden_Url").value;
WebImageViewer1.RemoteInvoked = Invalidate;
}
Now we'll make a simple JavaScript function that will increment or decrement the current page, and make sure we don't go too far:
function
Page(i){
var p = currentPage + i;
if (p > 0 && p <= numPages){
currentPage = p;
LoadFrame(p - 1);
}
}
One of the most important aspects of this example is the Invalidate function and the RemoteInvoked event. This basically tells the WebImageViewer to update the current view, because we've changed it remotely. Without this, you will not see anything happen when you click the next and previous buttons:
function
Invalidate(){
WebImageViewer1.Update();
}
When we're all done, your server side code should look like this:
private void Page_Load(object sender, System.EventArgs e)
{
if (!Page.IsPostBack)
{
string url = "myMultipageTiff.tiff";
this.Hidden_Pages.Value = RegisteredDecoders.GetImageInfo(Page.MapPath(url)).FrameCount;
this.Hidden_Url.Value = url;
this.WebImageViewer1.OpenUrl(url);
}
}
[RemoteInvokable]
public void Remote_LoadFrame(string url, int frame)
{
this.WebImageViewer1.OpenUrl(url, frame);
}
And your JavaScript should look like this:
<script type="text/javascript" language=javascript>
var numPages;
var currentPage = 0;
// Uses the atalaInitClientScript function to add a OnPageLoad to the onload event
atalaInitClientScript("OnPageLoad();");
function OnPageLoad(){
// Get the values of hidden tags
numPages = parseInt(document.getElementById("Hidden_Pages").value);
url = document.getElementById("Hidden_Url").value;
// Setup RemoteInvoked event handler
WebImageViewer1.RemoteInvoked = Invalidate;
}
// tells the WebImageViewer that it needs to update the image
function Invalidate(){
WebImageViewer1.Update();
}
// Increments and decrements the current page by the given amount
function Page(i){
var p = currentPage + i;
// Page number must be greater than 0
if (p > 0 && p <= numPages){
currentPage = p;
LoadFrame(p - 1);
}
}
// Uses RemoteInvoke to load a specified frameIndex from the current url
function LoadFrame(frameIndex){
WebImageViewer1.RemoteInvoke('Remote_LoadFrame', new Array(url, frameIndex));
}
</script>