tags:

views:

38

answers:

3

So, I have a load of database entries, each with an associated image file, and X and Y coordinates indicating which particular part of the image file it relates to. See the image and x1/y1/x2/y2 columns below

|  idx | code   | ref        | imagesub | image      | x1   | y1   | x2   | y2   |
-------+--------+------------+----------+------------+------+------+------+------+
| 5997 | MDX    | 1,1        | 1        | 02.png     |  38  |  216 |  717 |  436 |
| 5998 | MDX    | 1,2        | 1        | 02.png     |  38  |  375 |  720 |  478 |
| 5999 | MDX    | 1,3        | 1        | 02.png     |  38  |  448 |  709 |  597 |

I have a Django page for each of the entries, and I'd like to display only the relevant bit of the image - e.g. for entry 5997, I'd like to display just part of 02.png: (38,216) to (717,436).

What's the best way to do this? Is there a smart way to do it using some kind of JavaScript library?

Or should I write a script to chop up the images myself first, then rename them, and display the smaller images?

An alternative would be to display the entire image, but put some kind of highlight or frame around the relevant bits - if this is possible using JQuery or something similar?

Basically I can do whatever seems like the most sensible technical solution. I suppose it would be nice to show people a smaller image first (to reduce page loading time), then have the option of seeing the larger image with a frame around it.

So:

  1. is it possible to display just part of an image using JS: and
  2. is it possible to highlight part of an image, also with JS?

EDIT:

the jQuery Image Annotation Plugin looks good for Q2, maybe?

A: 

Probably best to cut up the images server side regardless. For one it is the only way to reduce loading time, and it sidesteps any sort of browser compatibility or disabled Javascript issues. Also, it is relatively easy especially if you can use Imagemagick, and if you need to do any resizing of the image, the quality will be better and consistent.

But as to your questions, yes and yes.

In fact you do not really need Javascript at all, CSS should do the job (though I guess that would be true of nearly all page layout manipulations...). The key is not to use the <img> element, as resizing that also scales and distorts the image attached to it. Use any generic element, even <a> if you want the image to be clickable:

a#image {
  display: block;
  background-image: url(someimage.png);
  background-position: 100px 250px;
  width: 500px;
  height: 700px;
}

Pretty simple stuff, should not have much issue with browser compatibility (though don't quote me on that).

If you want an area of the image highlighted you could put a <span> element inside the image containing element and style it like:

a#image span {
  position: absolute;
  top: 30px;
  left: 50px;
  width: 10px;
  height: 10px;
  background-color: orange;
  opacity: .7;
  display: block;
}

/* And make sure the containing image element has the right 'position' */
a#image { position: relative; }

All this is off the top of my head so you might need to do some experimenting, but the idea is there.

If you do not need to resize the image or save bandwidth, and you expect users to often view the full size image, setting such styles with Javascript might be beneficial. Still for most cases server side image manipulation is the way to go.

MooGoo
A: 

Actually there's a fairly easy way to do this, don't think in terms of <img>, think instead of background or background-image (the CSS properties).

I can't say exactly what your code looks like without knowing your platform, but if say you had the properties available in the page, I can show you the jQuery, like this:

//for (38,216) to (717,436)
var img = { x1: 38, x2: 717, y1: 216, y2: 436, url: "02.png" };

When you can just display the image in say a <div id="myImage"></div> like this:

$("#myDiv").css({
  width: img.x2 - img.x1,
  height: img.y2 - img.y1,
  background: "url('" + img.url + "')",
  backgroundPosition: -img.x1 + "px " + -img.y1 + "px"
});

You can view a demonstration here, another side benefit of this is that the user (for your example) would load 02.png only once, but use it multiple times, from cache. For more info the term that describe this/commonly used is CSS sprites, there are lots of articles out there around this.

If it doesn't need to be dynamic, you can of course render all of these properties directly out in the style attribute of the <div> directly, I'm just not exactly sure where the work has to be done (client vs server) here.

Nick Craver
A: 

The best way to do this is definitely CSS via technique called CSS sprites (basically the same thing MooGoo is advocating). There's no sense in resorting to javascript when the CSS solution will be much more widely supported by browsers.

The only reasons to actually split up the image on the server would be if your image was extremely large and the individual bits you wanted to display were small - otherwise, you'll actually see a performance benefit from serving the same image, as it'll be cached in the client's browser after the initial request.

Dexter
Yea, I was not thinking about server performance and cache, so with that in mind, CSS is the way to go. In the case of needing to downsize an image (thumbnails), the server should probably do the job, but even then the generated images should be saved in some kind of cache.
MooGoo