Thursday, November 25, 2010

FREE! ASP.net/C# IMDb Scraping API


In extension to my previous IMDb Scraping API in PHP, I have converted the code to ASP.net/C# based IMDb scraper. In my de facto development style, I have kept the code pretty simple and concise. For more details on the movie information it scraps, please refer to my previous post. I don’t have an IIS server running to demonstrate the code but it is functionally similar to my PHP Scraper API so you can test it on the link below. And above all... it’s FREE!!!

Test the Scraper API: http://lab.abhinayrathore.com/imdb/

Download C# Class file: http://lab.abhinayrathore.com/imdb/imdb_asp_csharp.htm
(Add this class file to your project and rename the namespace accordingly)
To convert this C# code to VB.net use this tool:
http://www.developerfusion.com/tools/convert/csharp-to-vb/

Fork it on GitHub: https://github.com/abhinayrathore/ASP.NET-IMDb-Scraper

Download DLL file: http://lab.abhinayrathore.com/imdb/IMDb.dll
(Copy this DLL file to your project folder and add it to the project references)

How to use this class:

  1. Include the class on your ASP page.
  2. Instantiate the class: IMDb imdb = new IMDb("The Godfather", true);
    (Second parameter is an optional Boolean value for scraping extra movie information.)
  3. Access the movie information using public variables: imdb.Id, imdb.Title etc.

It’s been a while since I worked on ASP.net, so if you have any improvements or suggestions, do let me know :)

Saturday, October 30, 2010

FREE! PHP IMDb Scraper/API for new IMDb Template


IMDb is undoubtedly the leading information source for media information and is the top target of web scraping for movie lovers around the world. Unfortunately IMDb does not provide an API to access its database so web scraping is the only resort for us. PHP being one of the most commonly used and powerful web development language enables easy web scraping with the power of PCRE (Perl Compatible Regular Expressions).

For my recent project on a Movie Catalog (http://movies.abhinayrathore.com), I needed a  IMDb scraper and found one built by Tyler Hall. His version was not robust enough to scrap all kind of movie pages so I extended it and made it more robust to support different type of titles, BUT recently IMDb changed its page template and most of the old scrapers stopped working including mine. So, I modified my scraper to accommodate the new template changes and considered it as my moral responsibility to contribute back to the developer community.

This new scraper is very robust and capable enough to handle a wide variety of new template modifications. Apart from the regular information it even goes deep to scan extra media images and release dates.

Click here for a Demo

Last Updated: Feb 1, 2014

Major changes in Feb 20, 2013 version:

  1. Now we use the combined information page to scrape the data. This page doesn't change quite often and we can get complete list of individual departments.
  2. Add a few more entities; producers, musicians, cinematographers, editors etc. Removed metascore information. Removed small poster url.
  3. You can now pass a second boolean parameter to the getMovieInfo() and getMovieInfoById() functions to disable the extra information. By default it is set to true and may slow down the scraping. If you don't need all the extra info like Storyline, Release Dates, Recommendations or Media Images, just pass false as second parameter to these methods. Example $movieArray = $imdb->getMovieInfo("The Godfather", false);.
  4. Information for individuals in the list of directors, cast, writers etc. is now in an associative array with key being the IMDb id of the individual.

UPDATE:
As some of you might have noticed, Google is preventing automated script access to its search result pages. I have created 2 search functions for Google and Bing so you can use whichever one works best for you. I have converted the code to use Bing as of now and will look for other alternatives if we run into some hurdles. Keep me updated if you have any better ideas :)

Here is a list of all the attributes it scraps from the IMDb page:

  1. TITLE_ID
  2. TITLE
  3. YEAR
  4. RATING
  5. GENRES
  6. STARS
  7. DIRECTORS
  8. WRITERS
  9. CAST
  10. PRODUCERS
  11. MUSICIANS
  12. CINEMATOGRAPHERS
  13. EDITORS
  14. ALSO_KNOWN_AS
  15. RELEASE_DATE
  16. RELEASE_DATES
  17. PLOT
  18. POSTER
  19. POSTER_LARGE
  20. RUNTIME
  21. TOP_250
  22. OSCARS
  23. AWARDS
  24. NOMINATIONS
  25. STORYLINE
  26. TAGLINE
  27. MEDIA_IMAGES
  28. MPAA_RATING
  29. VOTES
  30. RECOMMENDED_TITLES
  31. VIDEOS

How to use this PHP Scraper?
Include the class file on your php page
include("imdb.php");
Instantiate the class and get the results in an array:
$imdb = new Imdb();
$movieArray = $imdb->getMovieInfo("The Godfather");

You can try this scraper on my lab page: http://lab.abhinayrathore.com/imdb/

To download the PHP Source Code directly use this link: http://lab.abhinayrathore.com/imdb/imdb_php.htm

Fork it on GitHub: https://github.com/abhinayrathore/PHP-IMDb-Scraper

Example usage: http://lab.abhinayrathore.com/imdb/usage.htm

Proxy script for downloading or displaying Media images on your website: http://lab.abhinayrathore.com/imdb/imdbImage.txt

To implement you own IMDb Web Service API to return data in XML, JSON or JSONP format, use this script along with the API: http://lab.abhinayrathore.com/imdb/imdbWebService.htm

To implement IMDb.com's search suggestions on your website, please follow this post: http://web3o.blogspot.com/2011/10/imdb-search-suggestions-with-jquery.html

If you find any part of this scraper broken or incorrect, please drop a comment here and I’ll try to fix it as soon as possible.

IMDb has a leechers policy in place for media images. You may not be able to use the URL for some of the images to display on your website. As a workaround you can use a PHP Proxy to display or download those images. I’ve written a small proxy script to grab the images: http://lab.abhinayrathore.com/imdb/imdbImage.txt. To use this script you just need to pass the image URL as a request parameter:
<img src="imdbImage.php?url=<?=$url?>" />

NOTE: For users outside of USA
IMDb will automatically redirect you to titles listed in the language used for release in your country (Read more).
To see films listed under their original titles regardless of your country region you will have to modify this script to scrap the titles from http://akas.imdb.com because http://www.imdb.com will automatically redirect you to your country specific title page.

Happy Scraping :)

Friday, May 28, 2010

Google Maps: Dynamically Drawn and Resizable Polygon Overlay

In extension to my previous post on Dynamically Movable and Resizable Circle Overlay, I created yet another nifty tool to dynamically draw a polygon overlay on Google Maps. You won’t find another robust tool like this for Polygon drawing on the internet. Users can draw polygon dynamically by adding, deleting and moving the polygon boundary nodes. User can press shift+click on the map to add a new node to polygon boundary or they can press ctrl+click on any node marker to remove it. The node markers can be dragged around to resize the polygon.

This is how it looks like in action:
Google Maps Dynamic Polygon

The JavaScript code is pretty easy to modify for your custom needs. The initialize() function is used to initialize the Google Map object when the page loads. A click event is also added to the map for adding node markers on the map. The click event takes care of the case when the user click on the previous markers while holding the shift key. When the user clicks on the map, addMarker() function is called to add another boundary node to the polygon. For every newly added marker, drag events are assigned for resizing the polygon and a click event is assigned to delete the node when ctrl key is pressed while clicking the marker pin. The fitPolygon() function is used to set map bounds and center to adjust the polygon inside it.

Put the following JavaScript code in the head section of your page:

<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=YOUR_API_KEY&sensor=true" type="text/javascript"></script>
<script type="text/javascript">
/* Developed by: Abhinay Rathore [web3o.blogspot.com] */ 
//Global variables
var global = this;
var map;

var PolygonMarkers = []; //Array for Map Markers
var PolygonPoints = []; //Array for Polygon Node Markers
var bounds = new GLatLngBounds; //Polygon Bounds
var Polygon; //Polygon overlay object
var polygon_resizing = false; //To track Polygon Resizing

//Polygon Marker/Node icons
var redpin = new GIcon(); //Red Pushpin Icon
redpin.image = "http://maps.google.com/mapfiles/ms/icons/red-pushpin.png";
redpin.iconSize = new GSize(32, 32);
redpin.iconAnchor = new GPoint(10, 32);
var bluepin = new GIcon(); //Blue Pushpin Icon
bluepin.image = "http://maps.google.com/mapfiles/ms/icons/blue-pushpin.png";
bluepin.iconSize = new GSize(32, 32);
bluepin.iconAnchor = new GPoint(10, 32);

function initialize() { //Initialize Google Map
    if (GBrowserIsCompatible()) {
        map = new GMap2(document.getElementById("map_canvas")); //New GMap object
        map.setCenter(new GLatLng(38.90, -94.68007), 13);

        var ui = new GMapUIOptions(); //Map UI options
        ui.maptypes = { normal:true, satellite:true, hybrid:true, physical:false }
        ui.zoom = {scrollwheel:true, doubleclick:true};
        ui.controls = { largemapcontrol3d:true, maptypecontrol:true, scalecontrol:true };
        map.setUI(ui); //Set Map UI options

        //Add Shift+Click event to add Polygon markers
        GEvent.addListener(map, "click", function(overlay, point, overlaypoint) {
            var p = (overlaypoint) ? overlaypoint : point;
            //Add polygon marker if overlay is not an existing marker and shift key is pressed
            if (global.shiftKey && !checkPolygonMarkers(overlay)) { addMarker(p); }
        });
    }
}

// Adds a new Polygon boundary marker
function addMarker(point) {
    var markerOptions = { icon: bluepin, draggable: true };
    var marker = new GMarker(point, markerOptions);
    PolygonMarkers.push(marker); //Add marker to PolygonMarkers array
    map.addOverlay(marker); //Add marker on the map
    GEvent.addListener(marker,'dragstart',function(){ //Add drag start event
        marker.setImage(redpin.image);
        polygon_resizing = true;
    });
    GEvent.addListener(marker,'drag',function(){ drawPolygon(); }); //Add drag event
    GEvent.addListener(marker,'dragend',function(){   //Add drag end event
        marker.setImage(bluepin.image);
        polygon_resizing = false;
        drawPolygon();
        fitPolygon();
    });
    GEvent.addListener(marker,'click',function(point) { //Add Ctrl+Click event to remove marker
        if (global.ctrlKey) { removeMarker(point); }
    });
    drawPolygon();

    //If more then 2 nodes then automatically fit the polygon
    if(PolygonMarkers.length > 2) fitPolygon();
}

// Removes a Polygon boundary marker
function removeMarker(point) {
    if(PolygonMarkers.length == 1){ //Only one marker in the array
        map.removeOverlay(PolygonMarkers[0]);
        map.removeOverlay(PolygonMarkers[0]);
        PolygonMarkers = [];
        if(Polygon){map.removeOverlay(Polygon)};
    }
      else //More then one marker
      {
        var RemoveIndex = -1;
        var Remove;
        //Search for clicked Marker in PolygonMarkers Array
        for(var m=0; m<PolygonMarkers.length; m++)
        {
            if(PolygonMarkers[m].getPoint().equals(point))
            {
                RemoveIndex = m; Remove = PolygonMarkers[m]
                break;
            }
        }
        //Shift Array elemeents to left
        for(var n=RemoveIndex; n<PolygonMarkers.length-1; n++)
        {
            PolygonMarkers[n] = PolygonMarkers[n+1];
        }
        PolygonMarkers.length = PolygonMarkers.length-1 //Decrease Array length by 1
        map.removeOverlay(Remove); //Remove Marker
        drawPolygon(); //Redraw Polygon
      }
}

//Draw Polygon from the PolygonMarkers Array
function drawPolygon()
{
    PolygonPoints.length=0;
    for(var m=0; m<PolygonMarkers.length; m++)
    {
        PolygonPoints.push(PolygonMarkers[m].getPoint()); //Add Markers to PolygonPoints node array
    }
    //Add first marker in the end to close the Polygon
    PolygonPoints.push(PolygonMarkers[0].getPoint());
    if(Polygon){ map.removeOverlay(Polygon); } //Remove existing Polygon from Map
    var fillColor = (polygon_resizing) ? 'red' : 'blue'; //Set Polygon Fill Color
    Polygon = new GPolygon(PolygonPoints, '#FF0000', 2, 1, fillColor, 0.2); //New GPolygon object
    map.addOverlay(Polygon); //Add Polygon to the Map

    //TO DO: Function Call triggered after Polygon is drawn
}

//Fits the Map to Polygon bounds
function fitPolygon(){
    bounds = Polygon.getBounds();
    map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));
}
//check is the marker is a polygon boundary marker
function checkPolygonMarkers(marker) {
    var flag = false;
    for (var m = 0; m < PolygonMarkers.length; m++) {
        if (marker == PolygonMarkers[m])
        { flag = true; break; }
    }
    return flag;
}

//////////////////[ Key down event handler ]/////////////////////
//Event handler class to attach events
var EventUtil = {
      addHandler: function(element, type, handler){
            if (element.addEventListener){
                    element.addEventListener(type, handler, false);
            } else if (element.attachEvent){
                    element.attachEvent("on" + type, handler);
            } else {
                    element["on" + type] = handler;
            }
      }
};

// Attach Key down/up events to document
EventUtil.addHandler(document, "keydown", function(event){keyDownHandler(event)});
EventUtil.addHandler(document, "keyup", function(event){keyUpHandler(event)});

//Checks for shift and Ctrl key press
function keyDownHandler(e)
{
      if (!e) var e = window.event;
      var target = (!e.target) ? e.srcElement : e.target;
      if (e.keyCode == 16 && !global.shiftKey) { //Shift Key
            global.shiftKey = true;
      }
      if (e.keyCode == 17 && !global.ctrlKey) { //Ctrl Key
            global.ctrlKey = true;
      }
}
//Checks for shift and Ctrl key release
function keyUpHandler(e){
      if (!e) var e = window.event;
      if (e.keyCode == 16 && global.shiftKey) { //Shift Key
            global.shiftKey = false;
      }
      if (e.keyCode == 17 && global.ctrlKey) { //Ctrl Key
            global.ctrlKey = false;
      }
}
</script>

To initialize the map you can call the functions on page load event and include a div tag inside your body to hold the Map.

<body onload="initialize()" onunload="GUnload()">
<div id="map_canvas" style="width:100%; height:450px"></div>
</body>

Feel free to modify and use this code on your website. I have used API v2 for my code but you can easily modify this code for API v3. Happy Mapping!

Thursday, May 27, 2010

Google Maps: Dynamically Movable and Resizable Circle Overlay

Google provides a pretty wholesome Map API for creating customized maps with enhanced features. In a recent project of mine I had to use dynamically drawn map overlays for searching house properties within them. To implement that I looked for some algorithms to draw circles on Google Map Overlays and found a good one at http://koti.mbnet.fi/ojalesa/googlepages/circle.htm, but this program was built to change the radius using html form field. To take it a few steps further, I planned to make this circle movable and resizable by directly dragging map icons.

      This is one of the best dynamic circle overlay drawing tool you can find on internet. There are two pin markers to alter the circle, the Blue pin is used to drag the circle around on the map and the Red one can be dragged to resize the circle. You can even set minimum and maximum radius for the circle in the JavaScript code. The resize marker pin always stays at the 0 degree edge of the circle. The Circle fill color changes to red if the circle is moved or resized.

This is how it looks like in action: 

Google Map Dynamic Circle

JavaScript code: The logistic code is pretty easy to modify for your custom needs. The initialize() function is used to initialize the Google Map object when the page loads. Circle Center and Resize markers are then added at the default center location. Marker drag events are assigned to Center and Resize markers for dragging and resizing the circle. The drawCircle() function implements the algorithm for drawing the circle and finally the fitCircle() function is used to set the Map bounds to include the full circle inside it. If you want to trigger any other function after the circle is drawn, you can call your function after the fitCircle() function call at the end of drawCircle() function. Google Map uses Metric Units for distance by default, you will have to use conversion factor (1km = 0.621371192mi) to convert radius value into miles if you wish to.

Place the following JavaScript code in the head section of your page:
<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=YOUR_API_KEY&sensor=true" type="text/javascript"></script>
<script type="text/javascript">
/* Developed by: Abhinay Rathore [web3o.blogspot.com] */
//Global variables
var map;
var bounds = new GLatLngBounds; //Circle Bounds
var map_center = new GLatLng(38.903843, -94.680096);

var Circle; //Circle object
var CirclePoints = []; //Circle drawing points
var CircleCenterMarker, CircleResizeMarker;
var circle_moving = false; //To track Circle moving
var circle_resizing = false; //To track Circle resizing
var radius = 1; //1 km
var min_radius = 0.5; //0.5km
var max_radius = 5; //5km

//Circle Marker/Node icons
var redpin = new GIcon(); //Red Pushpin Icon
redpin.image = "http://maps.google.com/mapfiles/ms/icons/red-pushpin.png";
redpin.iconSize = new GSize(32, 32);
redpin.iconAnchor = new GPoint(10, 32);
var bluepin = new GIcon(); //Blue Pushpin Icon
bluepin.image = "http://maps.google.com/mapfiles/ms/icons/blue-pushpin.png";
bluepin.iconSize = new GSize(32, 32);
bluepin.iconAnchor = new GPoint(10, 32);

function initialize() { //Initialize Google Map
    if (GBrowserIsCompatible()) {
        map = new GMap2(document.getElementById("map_canvas")); //New GMap object
        map.setCenter(map_center);

        var ui = new GMapUIOptions(); //Map UI options
        ui.maptypes = { normal:true, satellite:true, hybrid:true, physical:false }
        ui.zoom = {scrollwheel:true, doubleclick:true};
        ui.controls = { largemapcontrol3d:true, maptypecontrol:true, scalecontrol:true };
        map.setUI(ui); //Set Map UI options

        addCircleCenterMarker(map_center);
        addCircleResizeMarker(map_center);
        drawCircle(map_center, radius);
    }
}

// Adds Circle Center marker
function addCircleCenterMarker(point) {
    var markerOptions = { icon: bluepin, draggable: true };
    CircleCenterMarker = new GMarker(point, markerOptions);
    map.addOverlay(CircleCenterMarker); //Add marker on the map
    GEvent.addListener(CircleCenterMarker, 'dragstart', function() { //Add drag start event
        circle_moving = true;
    });
    GEvent.addListener(CircleCenterMarker, 'drag', function(point) { //Add drag event
        drawCircle(point, radius);
    });
    GEvent.addListener(CircleCenterMarker, 'dragend', function(point) { //Add drag end event
        circle_moving = false;
        drawCircle(point, radius);
    });
}

// Adds Circle Resize marker
function addCircleResizeMarker(point) {
    var resize_icon = new GIcon(redpin);
    resize_icon.maxHeight = 0;
    var markerOptions = { icon: resize_icon, draggable: true };
    CircleResizeMarker = new GMarker(point, markerOptions);
    map.addOverlay(CircleResizeMarker); //Add marker on the map
    GEvent.addListener(CircleResizeMarker, 'dragstart', function() { //Add drag start event
        circle_resizing = true;
    });
    GEvent.addListener(CircleResizeMarker, 'drag', function(point) { //Add drag event
        var new_point = new GLatLng(map_center.lat(), point.lng()); //to keep resize marker on horizontal line
        var new_radius = new_point.distanceFrom(map_center) / 1000; //calculate new radius
        if (new_radius < min_radius) new_radius = min_radius;
        if (new_radius > max_radius) new_radius = max_radius;
        drawCircle(map_center, new_radius);
    });
    GEvent.addListener(CircleResizeMarker, 'dragend', function(point) { //Add drag end event
        circle_resizing = false;
        var new_point = new GLatLng(map_center.lat(), point.lng()); //to keep resize marker on horizontal line
        var new_radius = new_point.distanceFrom(map_center) / 1000; //calculate new radius
        if (new_radius < min_radius) new_radius = min_radius;
        if (new_radius > max_radius) new_radius = max_radius;
        drawCircle(map_center, new_radius);
    });
}

//Draw Circle with given radius and center
function drawCircle(center, new_radius) {
    //Circle Drawing Algorithm from: http://koti.mbnet.fi/ojalesa/googlepages/circle.htm

    //Number of nodes to form the circle
    var nodes = new_radius * 40;
    if(new_radius < 1) nodes = 40;

    //calculating km/degree
    var latConv = center.distanceFrom(new GLatLng(center.lat() + 0.1, center.lng())) / 100;
    var lngConv = center.distanceFrom(new GLatLng(center.lat(), center.lng() + 0.1)) / 100;

    CirclePoints = [];
    var step = parseInt(360 / nodes) || 10;
    var counter = 0;
    for (var i = 0; i <= 360; i += step) {
        var cLat = center.lat() + (new_radius / latConv * Math.cos(i * Math.PI / 180));
        var cLng = center.lng() + (new_radius / lngConv * Math.sin(i * Math.PI / 180));
        var point = new GLatLng(cLat, cLng);
        CirclePoints.push(point);
        counter++;
    }
    CircleResizeMarker.setLatLng(CirclePoints[Math.floor(counter / 4)]); //place circle resize marker
    CirclePoints.push(CirclePoints[0]); //close the circle polygon
    if (Circle) { map.removeOverlay(Circle); } //Remove existing Circle from Map
    var fillColor = (circle_resizing || circle_moving) ? 'red' : 'blue'; //Set Circle Fill Color
    Circle = new GPolygon(CirclePoints, '#FF0000', 2, 1, fillColor, 0.2); //New GPolygon object for Circle
    map.addOverlay(Circle); //Add Circle Overlay on the Map
    radius = new_radius; //Set global radius
    map_center = center; //Set global map_center
    if (!circle_resizing && !circle_moving) { //Fit the circle if it is nor moving or resizing
        fitCircle();
        //Circle drawing complete trigger function goes here

    }
}

//Fits the Map to Circle bounds
function fitCircle() {
    bounds = Circle.getBounds();
    map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));
}
</script>

To initialize the map you can call the functions on page load event and include a div tag inside your body to hold the Map.

<body onload="initialize()" onunload="GUnload()">
<div id="map_canvas" style="width:100%; height:450px"></div>
</body>

Feel free to modify and use this code on your website. I have used API v2 for my code but you can easily modify this code for API v3. Happy Mapping!

Wednesday, March 24, 2010

JavaScript and jQuery Image Magnifier

In an alternate version to the Image Magnification tool from my previous post, I have created another magnification tool which works exactly like a magnification glass moving over the picture. This tool is more concise and easy to use then the previous one where a separate popup with the same aspect ratio was used to display the image. Here the magnified image section keeps moving with the mouse providing an exact magnification glass effect. You also don’t need any separate CSS for the magnification window.

Why should you use this Image Magnification tool:

  1. Zero coding required.
  2. No CSS required at all.
  3. Can be triggered automatically or manually from the image.
  4. Works on images of any resolution or aspect ratio.

For testing I have used a very high resolution image of Taj Mahal (4300x2724 pixels).

This is how it looks in action:JavaScript Image MagnifierThe JavaScript code is very easy to understand and modify. The only thing you will need to modify for automatic magnification functionality is the $(document).ready() function where the jQuery Selectors needs to be modified to point to the images in your HTML document. You can also change the magnifier window size by changing the magnifier_size variable in the JavaScript Code.

Place the following JavaScript Code in the head section of your HTML page:
<script type="text/javascript"  src="http://code.jquery.com/jquery-latest.js"></script> 
<script type="text/javascript">
/* Developed by: Abhinay Rathore [web3o.blogspot.com] */
$(document).ready(function(){
      $(".magnify").mousemove(function(event){ moveMagnifier(this, event); });
      $(".magnify").mouseout(function(event){ hideMagnifier(); });
});

var magnifier_size = 200; //Change Magnifier size here.
var cursor_offset = 10; //Change Cursor Offset here.
var ratio, mHalf, pic_offset;
function showMagnifier(picId, e){ //Show Magnifier
      hideMagnifier();
      //Create and add magnified image to the body
      var magnifier = document.createElement("img");
      magnifier.id = "magnifier"
      magnifier.src = picId.src;
      magnifier.style.position = "absolute";
      document.body.appendChild(magnifier);
      //Calculate size ratio of original and magnified images
      ratio = magnifier.width / $(picId).width();
      mHalf = magnifier_size / 2;
      pic_offset = $(picId).offset(); //Picture offset
      //Get mouse position on the image
      var picX = e.pageX - pic_offset.left;
      var picY = e.pageY - pic_offset.top;
      clipImage(magnifier, picX, picY); //Clip the magnified image
      //Position the magnified image next to mouse cursor
      positionImage(magnifier, picX, picY, e.pageX, e.pageY)
}
function moveMagnifier(picId, e){ //Move Magnifier
      var magnifier = document.getElementById("magnifier");
      if(magnifier){ //If magnified image exists...
            //Get mouse position on the image
            var picX = e.pageX - pic_offset.left;
            var picY = e.pageY - pic_offset.top;
            clipImage(magnifier, picX, picY); //Clip the magnified image
            //Position the magnified image next to mouse cursor
            positionImage(magnifier, picX, picY, e.pageX, e.pageY)
      } else { //If magnified image does not exist...
            showMagnifier(picId, e);
      }
}
function clipImage(magnifier, picX, picY){ //Clip magnified image...
      var centerX = picX * ratio;
      var centerY = picY * ratio;
      $(magnifier).css("clip", "rect(" + Math.round(centerY - mHalf)  + "px," +
                                                   Math.round(centerX + mHalf) + "px," +
                                                   Math.round(centerY + mHalf) + "px," +
                                                   Math.round(centerX - mHalf) + "px)");
}
function positionImage(magnifier, picX, picY, pageX, pageY){  //Position magnified image...
      $(magnifier).css({'top': pageY - (picY * ratio) + mHalf + cursor_offset,
                         'left': pageX - (picX * ratio) + mHalf + cursor_offset});
}
function hideMagnifier(){ //Hide Magnifier
      $("#magnifier").remove(); //Remove the Magnifier Image
}
</script>

The CSS code I have used here is only to display the original images on the HTML page. You can use you own CSS styles and use the image class in the jQuery Selectors. You actually don’t need any CSS code to use this tool. You can use it directly by assigning mouse events to your images manually.
<style type="text/css">
.magnify{
      width: 500px;
      height: auto;
      cursor: crosshair;
}
</style>

The HTML Code for this image magnifier is very simple to use. If you are using CSS layout then you can use jQuery Selectors to select the images automatically.
<img class="magnify" src="taj.jpg" />

If you want to assign Magnification feature to your images manually, you can add mouse events to your images as shows below: 
<img src="taj.jpg" style="width:500px" onmousemove="moveMagnifier(this, event)" onmouseout="hideMagnifier()" />