Blitting an image, to another

  • Thread starter Arnaud Diederen
  • Start date
A

Arnaud Diederen

Hello everyone, and happy new year to all c.l.j'ers!

No bad code to post, just a question.

I wrote a JavaScript application that lets users view an image, and
zoom on it.

The way I "zoom" is pretty simple, really (I hope that your
newsreaders displays text with a monospace font..) :

Original image:
+-------------+ <=- <img>, absolutely positionned
|.....''''''''| inside a <div style="overflow:hidden;">
|.....' '<=- The user zooms that area
|.....''''''''|
+-------------+

Zoomed image (x2):
+-------------------------+ <=- <img>
|ooooooooooooooooooooooooo|
|ooooooooo+-------------+ <=- <div>
|ooooooooo|ooooooooooooo|o|
|ooooooooo|ooooooooooooo|o|
|ooooooooo|ooooooooooooo|o|
|ooooooooo+-------------+o|
|ooooooooooooooooooooooooo|
+-------------------------+


And now, with words: I re-scale the <img>, re-position it in the
<div>, and let the overflow:hidden clipping do the rest.

That works pretty fine, except that:

1) The interpolation is, of course, linear, giving some hard-to-read
pixel soup

2) If the user zooms a very small area, the <img> has to be re-scaled
by a possibly big factor. In both FF and IE, that can eat up a lot
of memory (too much, actually, crashing the browser). That's
... bad.


----

What I'd like to do:

Give the user a zoomed-in version of the image, without using a
re-scaling hack.

How would you do that? Does anyone know what would be the best method
to do it?

It must be working in IE and FireFox. I can use any technology that's
available with these browsers, as long as it's scriptable with
javascript.

Any idea can help!


Thanks, and best regards
Arnaud
 
T

Thomas 'PointedEars' Lahn

Arnaud said:
Hello everyone, and happy new year to all c.l.j'ers!

Thanks, to you too.
[...]
And now, with words: I re-scale the <img>, re-position it in the
<div>, and let the overflow:hidden clipping do the rest.

That works pretty fine, except that:

1) The interpolation is, of course, linear, giving some hard-to-read
pixel soup

2) If the user zooms a very small area, the <img> has to be re-scaled
by a possibly big factor. In both FF and IE, that can eat up a lot
of memory (too much, actually, crashing the browser). That's
... bad.
----

What I'd like to do:

Give the user a zoomed-in version of the image, without using a
re-scaling hack.

How would you do that? Does anyone know what would be the best method
to do it?

Use two or more images. 2) will be difficult to do, if that.


PointedEars
 
A

Arnaud Diederen

Thomas 'PointedEars' Lahn said:
Arnaud said:
Hello everyone, and happy new year to all c.l.j'ers!

Thanks, to you too.
[...]
And now, with words: I re-scale the <img>, re-position it in the
<div>, and let the overflow:hidden clipping do the rest.

That works pretty fine, except that:

1) The interpolation is, of course, linear, giving some hard-to-read
pixel soup

2) If the user zooms a very small area, the <img> has to be re-scaled
by a possibly big factor. In both FF and IE, that can eat up a lot
of memory (too much, actually, crashing the browser). That's
... bad.
----

What I'd like to do:

Give the user a zoomed-in version of the image, without using a
re-scaling hack.

How would you do that? Does anyone know what would be the best method
to do it?

Use two or more images. 2) will be difficult to do, if that.


Thanks for your reply, Thomas.

I've just thought of a solution that might work for FF:

Use a <canvas> instead of an <img>; then load the <img> in the
background, and blit the portion of the <img> in the <canvas>. That
should do: <URL:
http://developer.mozilla.org/en/docs/Canvas_tutorial:Using_images#Slicing>

Now, I need something pretty similar for IE.
Looking at the code of "excanvas" (<URL:
http://excanvas.sourceforge.net/>)
reveals that the 'drawImage()' operation is implemented, and so it
might work as well, but uses the 'img.src' attribute of the <img>. I
thought maybe there is another option, that'd smell a tad more like a
"native copy operation", if I may say so.. (i.e., something that
wouldn't rely on the cache)

Again, if anybody has _any_ idea at all, they're very, very welcome!

Best regards,
Arnaud
 
T

Thomas 'PointedEars' Lahn

Arnaud said:
Thomas 'PointedEars' Lahn said:
Arnaud said:
[...]
And now, with words: I re-scale the <img>, re-position it in the
<div>, and let the overflow:hidden clipping do the rest.

That works pretty fine, except that:

1) The interpolation is, of course, linear, giving some hard-to-read
pixel soup

2) If the user zooms a very small area, the <img> has to be re-scaled
by a possibly big factor. In both FF and IE, that can eat up a lot
of memory (too much, actually, crashing the browser). That's
... bad.
----

What I'd like to do:

Give the user a zoomed-in version of the image, without using a
re-scaling hack.

How would you do that? Does anyone know what would be the best method
to do it?
Use two or more images. 2) will be difficult to do, if that.

Thanks for your reply, Thomas.

I've just thought of a solution that might work for FF:

Use a <canvas> instead of an <img>; then load the <img> in the
background, and blit the portion of the <img> in the <canvas>. That
should do: <URL:
http://developer.mozilla.org/en/docs/Canvas_tutorial:Using_images#Slicing>

You don't need the proprietary `canvas' element for that.
[...]
Again, if anybody has _any_ idea at all, they're very, very welcome!

I used modified magnifier code from
<http://www.namibia-cd.com/menu/js/magnifier.htm> for
<http://rtc-ski.ch/magnifier.js> Go e.g. to
<http://rtc-ski.ch/ski/modelle/28er/28er> and click the magnifier icon
below to see it working on the ski. Also note that it was a quick hack.

But I'm afraid that unless you use `canvas', the image you load in the
background will have to be very large (and therefore slow to load) if
you need a context-sensitive zoom factor.


PointedEars
 
A

Arnaud Diederen

Thomas 'PointedEars' Lahn said:
[deletia]

I used modified magnifier code from
<http://www.namibia-cd.com/menu/js/magnifier.htm> for
<http://rtc-ski.ch/magnifier.js> Go e.g. to
<http://rtc-ski.ch/ski/modelle/28er/28er> and click the magnifier icon
below to see it working on the ski. Also note that it was a quick hack.

But I'm afraid that unless you use `canvas', the image you load in the
background will have to be very large (and therefore slow to load) if
you need a context-sensitive zoom factor.


Hi again Thomas,

that solution you're proposing has the same drawbacks as the one I was
using before: It requires a "big image".

Besides, in those examples, the "big image" has a fixed zoom factor,
against the "smaller image".
In my use-case, the user can zoom by box, and he's the one determining
the box extents, so I cannot possibly know how much the image will
have to be zoomed in.. (and the user might choose to zoom a very small
box on the original image, requiring it to be scaled by a huge factor
(x10000, for example)).

Thanks, though!

A.
 
T

Thomas 'PointedEars' Lahn

Arnaud said:
Thomas 'PointedEars' Lahn said:
I used modified magnifier code from
<http://www.namibia-cd.com/menu/js/magnifier.htm> for
<http://rtc-ski.ch/magnifier.js> Go e.g. to
<http://rtc-ski.ch/ski/modelle/28er/28er> and click the magnifier icon
below to see it working on the ski. Also note that it was a quick hack.

But I'm afraid that unless you use `canvas', the image you load in the
background will have to be very large (and therefore slow to load) if
you need a context-sensitive zoom factor.

[...]
that solution you're proposing has the same drawbacks as the one I was
using before: It requires a "big image".

Besides, in those examples, the "big image" has a fixed zoom factor,
against the "smaller image".
In my use-case, the user can zoom by box, and he's the one determining
the box extents, so I cannot possibly know how much the image will
have to be zoomed in.. (and the user might choose to zoom a very small
box on the original image, requiring it to be scaled by a huge factor
(x10000, for example)).

Hence my saying that either you will need a large big image that you can
scale with different zoom factors without artifacts or you will have to use
more than two images, depending on the user's choice. Consider the way
Google Maps does that.
Thanks, though!

You're welcome.


PointedEars
 
A

Arnaud Diederen

Thomas 'PointedEars' Lahn said:
[...]
that solution you're proposing has the same drawbacks as the one I was
using before: It requires a "big image".

Besides, in those examples, the "big image" has a fixed zoom factor,
against the "smaller image".
In my use-case, the user can zoom by box, and he's the one determining
the box extents, so I cannot possibly know how much the image will
have to be zoomed in.. (and the user might choose to zoom a very small
box on the original image, requiring it to be scaled by a huge factor
(x10000, for example)).

Hence my saying that either you will need a large big image that you can
scale with different zoom factors without artifacts or you will have to use
more than two images, depending on the user's choice. Consider the way
Google Maps does that.

Hi Thomas,

Google maps uses fixed-scales. I cannot afford that, unfortunately:
the user must be able to zoom to whatever box he/she chooses, so
that's not an option :|

Best regards,

A.
 
T

Thomas 'PointedEars' Lahn

Arnaud said:
Thomas 'PointedEars' Lahn said:
[...]
that solution you're proposing has the same drawbacks as the one I was
using before: It requires a "big image".

Besides, in those examples, the "big image" has a fixed zoom factor,
against the "smaller image".
In my use-case, the user can zoom by box, and he's the one determining
the box extents, so I cannot possibly know how much the image will
have to be zoomed in.. (and the user might choose to zoom a very small
box on the original image, requiring it to be scaled by a huge factor
(x10000, for example)).
Hence my saying that either you will need a large big image that you can
scale with different zoom factors without artifacts or you will have to use
more than two images, depending on the user's choice. Consider the way
Google Maps does that.

[...]
Google maps uses fixed-scales. I cannot afford that, unfortunately:
the user must be able to zoom to whatever box he/she chooses, so
that's not an option :|

You misunderstood me. I was referring to the way Google Maps loads images.
Of course I know you can't provide an image for every zoom level, but you
can provide say 5 images with increasing resolution and use each one for a
viable range of zoom levels.


PointedEars
 
A

Arnaud Diederen

Thomas 'PointedEars' Lahn said:
[...]
Google maps uses fixed-scales. I cannot afford that, unfortunately:
the user must be able to zoom to whatever box he/she chooses, so
that's not an option :|

You misunderstood me. I was referring to the way Google Maps loads images.
Of course I know you can't provide an image for every zoom level, but you
can provide say 5 images with increasing resolution and use each one for a
viable range of zoom levels.

I misunderstood you indeed!

That would be quite a good solution but, basically, I cannot fetch
more than 1 image (I know it sounds weird but,
basically, retrieving one of these images from the server triggers
rather heavy computing, and I cannot afford that).

So, that's not an option, alas :(

Again, thanks for the idea!

Best,
A.
 
T

Thomas 'PointedEars' Lahn

Arnaud said:
Thomas 'PointedEars' Lahn said:
Of course I know you can't provide an image for every zoom level, but
you can provide say 5 images with increasing resolution and use each
one for a viable range of zoom levels.

[...] That would be quite a good solution but, basically, I cannot fetch
more than 1 image (I know it sounds weird but, basically, retrieving one
of these images from the server triggers rather heavy computing, and I
cannot afford that).

So, that's not an option, alas :(

Would it be possible to compute the high-res image only once and then
serve only the best scaled variant of it on the fly with e.g. the use
of ImageMagick or GD Lib? If not, SVG appears to be more fitting.


PointedEars
 
A

Arnaud Diederen

Thomas 'PointedEars' Lahn said:
[...] That would be quite a good solution but, basically, I cannot fetch
more than 1 image (I know it sounds weird but, basically, retrieving one
of these images from the server triggers rather heavy computing, and I
cannot afford that).

So, that's not an option, alas :(

Would it be possible to compute the high-res image only once and then
serve only the best scaled variant of it on the fly with e.g. the use
of ImageMagick or GD Lib? If not, SVG appears to be more fitting.


Unfortunately not, as the data that composes the image is variable,
and potentially changes quite often; that would require the re-scaling
process to be run over and over again, potentially wasting a lot of
CPU power on the server.

Best,
Arnaud
 
A

Arnaud Diederen

Unfortunately not, as the data that composes the image is variable,
and potentially changes quite often; that would require the re-scaling
process to be run over and over again, potentially wasting a lot of
CPU power on the server.

Best,
Arnaud


Thomas,

just to let you know: I managed to get the results I wanted, using the
"matrix" filter, which will accept to resize the image (even by very
high factors), and not eat up all the memory to do so.

<URL:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2619310&SiteID=1>

Thanks for your suggestions,

A.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,521
Members
44,995
Latest member
PinupduzSap

Latest Threads

Top