scrolling an image


G

Guest

In free time I'm slowly progressing with my applet displaying
astronomical images. Now I would like to implement scroll bars around an
image.

The HTML defines so far <APPLET CODE=... WIDTH=512 HEIGHT=712>. Of
course if I run in the appletviewer I can freely resize it.

The applet itself is so far a JPanel divided horizontally in 3 equal
parts (a tabbed pane, a message text area, and a JTable). I plan to move
to a grid bag layout to make the tabbed pane somewhat taller.

One tab of the tabbed pane was a panel1 = new myDisplay();,
i.e. a custom JPanel where I display my images. Originally I displayed
there either a 256x256 ramp image, or a thumbnail image loaded from my
database (these are usually 197x197) which appeared centered.

Now I'd like to zoom the above thumbnail (which would require scroll
bars) as well as displaying larger images. I am currently testing with
1190x1190 images.

I wrapped the myDisplay in a scroll pane :

panel1 = new JScrollPane ( new myDisplay() ) ;

(so the tab added to the tab pane is still called panel1)

I declared that myDisplay extends JPanel implements Scrollable

In the myDisplay() constructor I added

setPreferredSize(new Dimension(256,256));

(if I did'nt do this no initial ramp image would be displayed, and no
focus for the keyboard commands I use to load further images would be
available)

To the myDisplay class I added the 5 methods for the Scrollable
interface. To stay simple,

- the getScrollableTracksViewportWidth() and
getScrollableTracksViewportHeight() return identically "false"

- the getScrollableUnitIncrement and getScrollableBlockIncrement
return respectively 1 and 50 (pixels ?) ... anyhow scrolling somehow
works, though slowly for larger images

- getPreferredScrollableViewportSize() simply returns
getPreferredSize();

The paintComponent method of the myDisplay class does :

- transfers into a global data array either the (FITS) image array
pre-loaded by a dedicated class, or build the ramp image

- I then call (and this is new for this scrollabe version)
setPreferredSize(new Dimension(naxis1,naxis2));

- then I scale the data array into a BufferedImage according to
a linear, log or histogram equalized ITT and using a proper LUT
and do a drawImage (plus appropriate overlays as instructed by
mouse and kbd commands, all this unchanged with respect to the
unscrolled version)

xoff=(size().width-naxis1)/2 ;
yoff=(size().height-naxis2)/2 ;
g2.drawImage(img,xoff,yoff,null) ;

Now in the non-scrolled version this was sufficient to center the
thumbnail image.

Now instead the ramp image appears in top left corner. Usually I have a
vertical scrollbar (scrolling reasonably fast).

If I load a thumbnail image from the db, it also goes in the top left
corner, and has no scrollbars. They appear if I resize the appletviewer
small enough.

If I load the larger (1190x1190) image, it originally appears in the
previous size, then, AS SOON AS I RESIZE THE WINDOW, it occupies the
full size, with scrollbars. Scrolling is however rather slow.

I have the impression there might be something odd with the coordinates.
Actually I'm reading coordinates via mouse, and the pixel and sky
coordinates appear converted correctly (by comparison with another image
display application). However commanded overlays do not appear.

Is there anything I should do about "viewports" in a custom scrollable
application like this ?

Is there anything I could do to make scroll faster ?

Does the setPreferredSize in paintComponent have counter-indications ?


Any further suggestion for an efficient way of implementing zoom
(otherwise I'd simply replicate the data array into a larger
BufferedImage with dimensions multiplied by the zoom factor) ?
 
Ad

Advertisements

K

Knute Johnson

LC's No-Spam Newsreading account said:
In free time I'm slowly progressing with my applet displaying
astronomical images. Now I would like to implement scroll bars around an
image.

The HTML defines so far <APPLET CODE=... WIDTH=512 HEIGHT=712>. Of
course if I run in the appletviewer I can freely resize it.

The applet itself is so far a JPanel divided horizontally in 3 equal
parts (a tabbed pane, a message text area, and a JTable). I plan to move
to a grid bag layout to make the tabbed pane somewhat taller.

One tab of the tabbed pane was a panel1 = new myDisplay();, i.e. a
custom JPanel where I display my images. Originally I displayed there
either a 256x256 ramp image, or a thumbnail image loaded from my
database (these are usually 197x197) which appeared centered.

Now I'd like to zoom the above thumbnail (which would require scroll
bars) as well as displaying larger images. I am currently testing with
1190x1190 images.

I wrapped the myDisplay in a scroll pane :

panel1 = new JScrollPane ( new myDisplay() ) ;

(so the tab added to the tab pane is still called panel1)

I declared that myDisplay extends JPanel implements Scrollable

In the myDisplay() constructor I added

setPreferredSize(new Dimension(256,256));

(if I did'nt do this no initial ramp image would be displayed, and no
focus for the keyboard commands I use to load further images would be
available)

To the myDisplay class I added the 5 methods for the Scrollable
interface. To stay simple,

- the getScrollableTracksViewportWidth() and
getScrollableTracksViewportHeight() return identically "false"

- the getScrollableUnitIncrement and getScrollableBlockIncrement
return respectively 1 and 50 (pixels ?) ... anyhow scrolling somehow
works, though slowly for larger images

- getPreferredScrollableViewportSize() simply returns
getPreferredSize();

The paintComponent method of the myDisplay class does :

- transfers into a global data array either the (FITS) image array
pre-loaded by a dedicated class, or build the ramp image

- I then call (and this is new for this scrollabe version)
setPreferredSize(new Dimension(naxis1,naxis2));

- then I scale the data array into a BufferedImage according to
a linear, log or histogram equalized ITT and using a proper LUT
and do a drawImage (plus appropriate overlays as instructed by
mouse and kbd commands, all this unchanged with respect to the
unscrolled version)

xoff=(size().width-naxis1)/2 ;
yoff=(size().height-naxis2)/2 ;
g2.drawImage(img,xoff,yoff,null) ;

Now in the non-scrolled version this was sufficient to center the
thumbnail image.

Now instead the ramp image appears in top left corner. Usually I have a
vertical scrollbar (scrolling reasonably fast).

If I load a thumbnail image from the db, it also goes in the top left
corner, and has no scrollbars. They appear if I resize the appletviewer
small enough.

If I load the larger (1190x1190) image, it originally appears in the
previous size, then, AS SOON AS I RESIZE THE WINDOW, it occupies the
full size, with scrollbars. Scrolling is however rather slow.

I have the impression there might be something odd with the coordinates.
Actually I'm reading coordinates via mouse, and the pixel and sky
coordinates appear converted correctly (by comparison with another image
display application). However commanded overlays do not appear.

Is there anything I should do about "viewports" in a custom scrollable
application like this ?

I don't think so. In fact I'm not clear as to why your component needed
to implement Scrollable.
Is there anything I could do to make scroll faster ?

Hard to tell without actual code but probably not. Get a faster
computer, faster video card and run it on Windows, all those will
improve performance.
Does the setPreferredSize in paintComponent have counter-indications ?
Yes.

Any further suggestion for an efficient way of implementing zoom
(otherwise I'd simply replicate the data array into a larger
BufferedImage with dimensions multiplied by the zoom factor) ?

Well it depends on what you actually mean by zoom. Are you displaying
your 1190x1190 images larger than that? If they get really big you
don't want to have to put the whole image in the scroll panel. You will
need some sort of control to select what part of the image you want to
see. Look at mapquest.com and see how they do their zooming and
scrolling for ideas.

Probably the best thing you could do is to really tell us in detail what
you want to end up with. That way we would have a better idea how to
get there.
 
A

Andrew Thompson

In free time I'm slowly progressing with my applet displaying
astronomical images. Now I would like to implement scroll bars around an
image.

The HTML defines so far <APPLET CODE=... WIDTH=512 HEIGHT=712>. Of
course if I run in the appletviewer I can freely resize it.

It should be possible to resize this applet's width,
<http://www.physci.org/test/resize/>
and here, full browser window.
<http://www.physci.org/test/resize/fullwnd5.html>

But why not make it a JFrame (launched using web-start)
that is automatically resizable? Check this applet/application
combo. to see the differences.
The applet itself is so far a JPanel divided horizontally in 3 equal
parts (a tabbed pane, a message text area, and a JTable). I plan to move
to a grid bag layout to make the tabbed pane somewhat taller.

Have you considered using nested layouts? Often
it is much simpler to achieve the effect required,
using nested layouts, than any other single layout.
That is especially tru of GBL, which is devilish.

..Knute probably answered the substantive question,
so I'll leave it at those few comments.
 
G

Guest

LC's No-Spam Newsreading account wrote:
In free time I'm slowly progressing with my applet displaying astronomical
images. Now I would like to implement scroll bars around an image.
Now I'd like to zoom the above thumbnail (which would require scroll bars)
as well as displaying larger images. I am currently testing with 1190x1190
images.
I wrapped the myDisplay in a scroll pane :
panel1 = new JScrollPane ( new myDisplay() ) ;
I declared that myDisplay extends JPanel implements Scrollable
In the myDisplay() constructor I added
setPreferredSize(new Dimension(256,256));
The paintComponent method of the myDisplay class does : [...]
- I then call (and this is new for this scrollabe version)
setPreferredSize(new Dimension(naxis1,naxis2));

Is there anything I should do about "viewports" in a custom scrollable
application like this ?

I don't think so. In fact I'm not clear as to why your component needed to
implement Scrollable.

Well, the vertical size of panel1 is limited. Say one third of the
screen (mine is 1280x1024, but others may have smaller ones) So it can
be higher then my image size, either because the actual image is bigger
(the 1190x1190) or the displayed image will be bigger (say a 197x197 at
zoom 2 with pixel replication will make a 394x394). So I should be able
to see only a part of it, but pan to the rest.

Having scroll bars seemed the way, and I thought that to have them one
had to implement Scrollable. Am I wrong ?
Hard to tell without actual code but probably not. Get a faster computer,
faster video card and run it on Windows, all those will improve performance.

Windows is out of question. We are a Linux factory. And zoom and pan
works fast enough in other applications, and also applets seen on the
web, so it must be some inefficiency in my code. I thought it could be
something in the very naive way I implemented Scrollable.

OK. I'd try moving it elsewhere. As a candidate, the constructor for
myDisplay defines an anonymous KeyAdapter. Its keyTyped method deals
with a keyboard command which loads the image from the net via my custom
method fitsAndRegion() ; and then calls repaint() ; I could stick
setPreferredSize in between (the image size will be globally known after
the fitsAndRegion() call).

Well it depends on what you actually mean by zoom.

I mean that if my image is 200x200 I would like to display e.g. a
400x400 image where each 2x2 SCREEN pixels will contain the same value
as the original image pixels, etc. Does zoom mean anything else ?
Probably the best thing you could do is to really tell us in detail
what you want to end up with. That way we would have a better idea
how to get there.

What I want to do is to emulate in an applet a subset of the behaviour
of the astronomical image display program "ds9". The purpose of this is
to validate the cross-identifications between several catalogues. To do
this I display "regions" (say a coloured circle whose radius is
proportional to source intensity, and whose colour depends on the
catalogue) over a sky image. In a JTable I have the list of regions with
other information, and with the mouse I can hilight a region and locate
it in the Jtable or viceversa. All this I have already. But the scale of
the image is such that at zoom 1 the regions will be too tiny and
packed.

The reason I want to emulate this in an applet is that I'd like to
interface it directly with our mysql database. So far I've done it using
our db query i/f and ds9 and XPA (a way of scripting ds9), but that
requires a lot of clicks. Also XPA is efficient for local use
(everything running on same machine or at least some network where the
data are), but I'd like to allow people elsewhere to participate to the
validation process.
 
G

Guest

must be some inefficiency in my code.

OK. I'd try moving it elsewhere. As a candidate, the constructor for
myDisplay defines an anonymous KeyAdapter. Its keyTyped method deals
with a keyboard command which loads the image from the net via my
custom method fitsAndRegion() ; and then calls repaint() ; I could
stick setPreferredSize in between (the image size will be globally
known after the fitsAndRegion() call).

I did this, and had at least the effect that scrolling is now reasonably
fast. I can click the arrows on the scrollbar and move by 1 pixel, I
can click in the scrollbar track and move by 100 pixel, I can even drag
the scrollbar knob, which before was virtually inactive.


I still observe a "funny" behaviour. Let's say that my top panel is a
rectangular area like this (height is LESS than 256)

........................
........................
........................
........................
........................

When I initialize the applet the 256x256 ramp is loaded in the top left
corner (NOT in the centre as I'd like) with part off-screen and a
vertical scrollbar

xxxxxxx................ v
xxxxxxx................ v
xxxxxxx................ v
xxxxxxx................ v
xxxxxxx................ v
ooooooo
ooooooo

When I load a smaller image (197x197) it is initially loaded centered
in the former display area, with part off screen on the bottom, and the
scroll bar remains present

........................ v
..xxxxxx................ v
..xxxxxx................ v
..xxxxxx................ v
..xxxxxx................ v
oooooo

Then, in a non-reproducible way after a while when I move the cursor
around, the image relocates in the top left corner and the scrollbar
disappears (this is OK, why hasn'it been done at the beginning ?)

xxxxxx.................
xxxxxx.................
xxxxxx.................
xxxxxx.................
xxxxxx.................

when I load a larger image (actually larger than the panel in both
dimensions), a part of it appears in the same area covered by the
previous smaller image (i.e. as above). Only if I resize the
appletviewer slightly, the full part of the image is displayed with both
horizontal and vertical scrollbars.


There is another thing I do not fully understand about paintComponent.
Currently I do the scaling of my data array into the BufferedImage here.
For debug I print to stdout some message about the scaling (only when
histogram equalization is active). Now these messages appear more than
once (not only when the image is initially loaded), so it looks like the
method is called more often than I'd expect.

In the past I noted that calling some other methods from within
paintComponent generated infinite loops.

Possibly I should move all the image scaling to a separate method, and
leave in paintComponent only the image display

g2.drawImage(img,xoff,yoff,null) ;

and the region overlay ?
 
Ad

Advertisements

G

Guest

I did this, and had at least the effect that scrolling is now reasonably
fast.
There is another thing I do not fully understand about paintComponent.
Currently I do the scaling of my data array into the BufferedImage
here.
Possibly I should move all the image scaling to a separate method, and
leave in paintComponent only the image display

I did this too, and the scrolling speed had an ultimate improvement, now
scrolling is instantaneous !!

There are side effects, like the unability to display a message in a
component not yet realized, or the initialization to an unexpected LUT,
or the fact a LUT change from a tab in the tabbed pane no longer
repaints the panel automatically, but I guess now I could debug that
myself !
 
Ad

Advertisements


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

Top