Caching image proxy

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Caching image proxy

Günther Schmidt
Hi,

I've got a CD with 100's of pictures. (No guys, no porn, art only! :-) ).

I'd like to create an app where I can view them all at once in a
scrolling window.

I've created an OrderedCollection with all the image filenames, roughly
700 entries.

On a Shell I have

Shell>>onViewOpened

        super onViewOpened.
        self model picturePaths do: [:each | ImagePresenter createIn: self on:
(OLEPicture fromFile: each)].

Clearly thats too much.

How would I go about using a proxy for the image?

Would it help, ie. does the view of the ImagePresenter let go of the
bitmap when it's not actually displayed?

Günther


Reply | Threaded
Open this post in threaded view
|

Re: Caching image proxy

Christopher J. Demers
"Günther Schmidt" <[hidden email]> wrote in message
news:[hidden email]...
> I've got a CD with 100's of pictures. (No guys, no porn, art only! :-) ).
>
> I'd like to create an app where I can view them all at once in a scrolling
> window.
....

I started developing something like that (a thumbnail viewer) a while ago.
I ran into a problem, and I have not had the time to get back to it.
However I can give you the benefit of my experience.  I recall needing to do
something to prevent all the images from being loaded into memory, but I
don't remember what I did.  I probably created a wrapper object that could
load the image on demand.  My wrapper may have had some intelligence about
caching and unloading images (I don't have the code at hand now).  However
all that turned out to be the least of my problems.  The limit I hit was the
maximum size of the container in a scroll view.  Windows can not handle a
view larger than a certain size.  Apparently the limit is  32767 pixels, you
can read some of my previous comments here: (watch the wrap)
http://groups-beta.google.com/group/comp.lang.smalltalk.dolphin/browse_thread/thread/1cc5b17ec5d0b527/dad4b4af46070527?#dad4b4af46070527 .

If I ever get back to working on my thumbnail viewer I will take a virtual
approach.  I will reuse a view full of ImagePresenters, the row that scrolls
out of view will be used to show the row that comes into to view.  I will
effectively emulate a scroll view, and there will be no size limitation.
This will require a few tricks, but it should not be hard to do.

Chris


Reply | Threaded
Open this post in threaded view
|

Re: Caching image proxy

Günther Schmidt
Christopher,

Christopher J. Demers wrote:
>
> I started developing something like that (a thumbnail viewer) a while ago.
> I ran into a problem, and I have not had the time to get back to it.
> However I can give you the benefit of my experience.  I recall needing to do
> something to prevent all the images from being loaded into memory, but I
> don't remember what I did.  I probably created a wrapper object that could
> load the image on demand.

I'm doing that via a DNUProxy (that I subclassed from ProtoObject).
It creates the image at first call of DNU via

PictureBroker>>objectForKey: aFilename

        ^self objects at: aFilename ifAbsentPut: [OLEPicture fromFile: Filename]

PictureBroker>>objects

        objects ifNil: [objects := WeakLookupTable new].
        ^objects




  My wrapper may have had some intelligence about
> caching and unloading images (I don't have the code at hand now).

Well actually to me that's still the trickiest part ...


  However
> all that turned out to be the least of my problems.  The limit I hit was the
> maximum size of the container in a scroll view.  Windows can not handle a
> view larger than a certain size.  Apparently the limit is  32767 pixels, you
> can read some of my previous comments here: (watch the wrap)
> http://groups-beta.google.com/group/comp.lang.smalltalk.dolphin/browse_thread/thread/1cc5b17ec5d0b527/dad4b4af46070527?#dad4b4af46070527 .
>

that's a very interesting post, but it still doesn't really answer
anything about an intelligent caching/release mechanism.

I suppose the view would have to trigger the load / release somehow.

> If I ever get back to working on my thumbnail viewer I will take a virtual
> approach.  I will reuse a view full of ImagePresenters, the row that scrolls
> out of view will be used to show the row that comes into to view.  I will
> effectively emulate a scroll view, and there will be no size limitation.
> This will require a few tricks, but it should not be hard to do.
>
> Chris
>
>

please keep me posted,

thanks

Günther


Reply | Threaded
Open this post in threaded view
|

Re: Caching image proxy

Christopher J. Demers
"Günther Schmidt" <[hidden email]> wrote in message
news:42c32859$[hidden email]...
...
>  My wrapper may have had some intelligence about
>> caching and unloading images (I don't have the code at hand now).
>
> Well actually to me that's still the trickiest part ...
...
> that's a very interesting post, but it still doesn't really answer
> anything about an intelligent caching/release mechanism.
>
> I suppose the view would have to trigger the load / release somehow.
...
I have had a look at my code now, remember that it was expirimental, and
quite old according to the timestamps and the formatting may not survive the
post.  The method bellow is called when the scroll container is scrolled.
It looks like I had not added support for freeing images when it is scrolled
the other way.  Certainly that should be handled as well.
==================
onScrolled: anPositionEvent
"cdemers - 8/31/2002 Free the photos of presenters that have scrolled off
the screen at the top. This is required to conserve memory when working with
full size files."
"Transcript nextPutAll: anPositionEvent position displayString; cr."
| yPos |
yPos := anPositionEvent position y abs.
thumbnailPresenters do: [:eachTp |
eachTp view rectangle bottomRight y < yPos ifTrue: [eachTp freePhoto]].
=================
This is what my freePhoto method looks like.  The Image will reload itself
so long as it has a fileLocator.
=================
freePhoto
"cdemers - 8/31/2002 Free the photo to save memory."
"cdemers - 8/31/2002 Only free the photo if we can get it again, ie don't
free photos loaded from memory."
thumbnailPresenter model value fileLocator notNil
ifTrue: [thumbnailPresenter model value free].
=================

I hope this helps, just watch out for the maximum view size.  I really think
that a more virtual approach would be better.

Chris


Reply | Threaded
Open this post in threaded view
|

Re: Caching image proxy

Chris Uppal-3
In reply to this post by Günther Schmidt
Günther,

> I've got a CD with 100's of pictures. (No guys, no porn, art only! :-) ).

Right.  We all believe you...

;-)


> I'd like to create an app where I can view them all at once in a
> scrolling window.

I think you'll have to take a rather roundabout route; the "normal" MVP
components simply do not provide the necessary support.

The problem is scrolling, and specifically the way that the ScrollingDecorator
works. If you want to display, say, a 2000x2000 pixel sub-component, then what
it does is it actually creates a sub-component of that size, and then uses its
own scrollbars to move the sub-component around.  For small-ish sub-components
this works really well.  It is simple (the sub-component doesn't know
/anything/ about scrolling) and can be very fast if the sub-component is
double-buffered.   Unfortunately it doesn't scale to the kinds of sizes that
you will need.

In the first place there's a limit on how big a double-buffer for the
sub-component can be -- I think it's memory limited, on my machine I can create
a 2000x4000 Bitmap, or a 4000x2000 one, but I can't create a 4000x4000 one.
That means that you can't use a big double-buffered sub-component, and
therefore you will suffer unpleasant flicker when you, say, resize the window.

The second problem is that even a unbuffered sub-component is limited by the
maximum size of a Window, which is 32k x 32k pixels -- which is probably too
small for your purposes.

So, what I think you will need to do is take control of the scrolling yourself.
Then you can use the vertical scroll offset to decide which image(s) should be
displayed in the visible window.  Once you have done that, the client extent of
your display window will be just the visible window itself, so you can easily
use double-buffering (since the buffer need not be large).  The problem is that
you will have to write your own scrolling logic (more below).  You may well
want to keep track of which image files are currently open and close unneeded
ones as they are scrolled out of sight (maybe keeping them open until they have
scrolled some distance away, so as to allow back-and-forth scrolling without
irritating delays).  A minor irritation is that you'll probably have to open
and read all the files before you start, otherwise you won't know the total
height of the images.

BTW, you won't be able to use the existing ImagePresenter/ImageView, you will
probably have to create your own View class for this (even without the
scrolling problems, which make them unsuitable, I doubt if it is feasible to
make a proxy Image -- at least it would probably be more work than creating a
simple new View).

There are two ways to do your own scrolling.  One is to use your own ScrollBars
(the 'scroll bar' view resources of NumberPresenter).  I have never used that
myself, so I don't know how easy that would be; it doesn't /look/ too hard.
The alternative (which I have used) is to turn on the WS_HSCROLL and WS_VSCROLL
bits in the view's #basicStyleMask -- unfortunately you then have to do a fair
amount of messing around to tell windows what the scrollable ranges are, handle
scrolling events, and so on...

Anyway, assuming that you have your own scrollbars (however implemented) you
can then keep track of the scroll position(s), and use them to choose which
(parts
of) which images images to draw in the display view.

Rather a lot of work, I'm afraid...

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: Caching image proxy

Günther Schmidt
Chris,

thanks,

Chris Uppal wrote:
>
> Rather a lot of work, I'm afraid...
>
>     -- chris
>

I *must* be cursed or something. I always run into such things at the end.

I wanted to associate the pictures with the appropriate artists which I
first have to import from a php based web application.

I wanted to do this via drag&drop, I guess I'll use FolderPresenter for
the images themselves, and just use some sort of icon instead.

When somebody wants to actually view the images from an artist I'll pass
that to the Windows image viewer and let it deal with it.

Günther


Reply | Threaded
Open this post in threaded view
|

Re: Caching image proxy

Christopher J. Demers
"Günther Schmidt" <[hidden email]> wrote in message
news:42c3da67$[hidden email]...

> Chris Uppal wrote:
>>
>> Rather a lot of work, I'm afraid...
>>
>>     -- chris
>>
>
> I *must* be cursed or something. I always run into such things at the end.
>
> I wanted to associate the pictures with the appropriate artists which I
> first have to import from a php based web application.
>
> I wanted to do this via drag&drop, I guess I'll use FolderPresenter for
> the images themselves, and just use some sort of icon instead.
>
> When somebody wants to actually view the images from an artist I'll pass
> that to the Windows image viewer and let it deal with it.

I completely agree with Chris's recommendation to emulate the scrolling.
However I do think one could implement this approach using ImagePresenters
in a composite way (though I have not actually done this).  I did once
implement an emulated grid view using StaticText and TextEdit views.  I
would send disableRedraw, reposition the views, and then send enableRedraw
and invalidate the view.  It worked pretty well in that case.  If you set
the scroll increment so that it scrolls by one row of images at a time I
think this might work.  The thumbnail program I previously mentioned was an
interface to an image cataloging program, and I used drag/drop to classify
my photos.  It worked really well, except for the maximum view size
limitation in the scrolling container, which is why scrolling really should
be emulated.

If you decide not to use ImagePresenters you may want to look at the Windows
Shell interface here
http://www.dolphinharbor.org/dh/projects/shell/index.html .  I have not used
it, but I wonder if it might allow you to use something like an explorer
thumbnail view.  If so that might make your life easier.

Chris