Resizing/caching/buffering images from internet?

Got a LiveCode personal license? Are you a beginner, hobbyist or educator that's new to LiveCode? This forum is the place to go for help getting started. Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller

Post Reply
n9yty
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 52
Joined: Thu Feb 28, 2013 11:33 pm

Resizing/caching/buffering images from internet?

Post by n9yty » Wed Mar 13, 2013 6:09 pm

Hi,

I have tried several approaches which have all come up empty, so rather than show my ignorance publicly :oops: I thought I would just ask as an open-ended question.

I am pulling some images from a web site to stage in a data grid view. Obviously, they are much larger on the web site than the little version I need in my data grid. However, I have not yet managed to find a good solution to resize them in LiveCode and further to be sure that they are buffered/cached so that when you leave the card and come back to it you don't have such a long delay.

Right now I just have the image object sized small, and I am pulling the images in via load URL so that they become cached (as I understand it anyway), but going from the grid to another card is fine but the trip back to the data grid card has a delay of about two and a half to three seconds on my Android device. The data grid has ten rows each with an image on it, so I am not sure if the delay is in the resizing, rendering, or what. The desktop app switching is instant.

Thanks for any thoughts on how to resize/cache/buffer the images for best performance.

Mark
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 5150
Joined: Thu Feb 23, 2006 9:24 pm
Contact:

Re: Resizing/caching/buffering images from internet?

Post by Mark » Thu Mar 14, 2013 11:25 am

Hi,

First of all, make sure not to download a picture a second time. You can keep the status of a picture in a separate text file, which means that you never need to download it again.

Third, after downloading an image and setting the text of an image control to the downloaded data, resize that picture, get the imagedata, set the text property to empty and then set its imagedata back to the resized imagedata. Now, you'll have an image control that takes little memory and renders quickly and you can use this in the data grid. You can also save the resized imagedata to disk (SD card) to keep it available for a next session.

kind regards,

Mark
The biggest LiveCode group on Facebook: https://www.facebook.com/groups/livecode.developers
The book "Programming LiveCode for the Real Beginner"! Get it here! http://tinyurl.com/book-livecode

n9yty
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 52
Joined: Thu Feb 28, 2013 11:33 pm

Re: Resizing/caching/buffering images from internet?

Post by n9yty » Thu Mar 14, 2013 2:37 pm

Mark wrote:Hi,

First of all, make sure not to download a picture a second time. You can keep the status of a picture in a separate text file, which means that you never need to download it again.

Third, after downloading an image and setting the text of an image control to the downloaded data, resize that picture, get the imagedata, set the text property to empty and then set its imagedata back to the resized imagedata. Now, you'll have an image control that takes little memory and renders quickly and you can use this in the data grid. You can also save the resized imagedata to disk (SD card) to keep it available for a next session.
Thanks for the thoughts... I'm not sure what you mean about "text of an image", do you mean the filename property?

I'll have to think this through on where to do what...

Perhaps as I parse the HTML of the page, for each img tag I want to handle put it in a temporary (invisible) image container via the filename property, set the size of that image object as I want it, now I have resized imageData, then... As I am doing this on the card that is prepping for the data grid, would I save this imageData out to a file for caching and then pass the information to the datagrid about where to pull it? Seems wasteful to have a two-way filesystem trip here for the initial display of the image. Or, since I am pulling images in by a certain number at a time, should I have a placeholder card that can hold a given set of images, and have it decide when one is requested from the internet if it is already in the cache to load from storage or from the net, and then tell the datagrid which of these placeholder images objects to pull its image data from? That is kind of what I was doing before as a resize effort (minus the caching) but I was running into some odd problems so I will have to revisit that.

I also would have to save the timestamp of the image, or when it was retrieved, because of the rate they are replaced--it would cause storage issues before long if I cache them all to local storage. But certainly, especially for the mobile app, this will be a huge benefit for data usage requirements.

jmburnod
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 2729
Joined: Sat Dec 22, 2007 5:35 pm
Contact:

Re: Resizing/caching/buffering images from internet?

Post by jmburnod » Thu Mar 14, 2013 3:12 pm

Hi n9yty ,
I'm not sure what you mean about "text of an image", do you mean the filename property?
No,
The text of an image is the binary data of the image.
The filename of an image is the path of an image file

Kind regards
Jean-Marc
https://alternatic.ch

sturgis
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 1685
Joined: Sat Feb 28, 2009 11:49 pm

Re: Resizing/caching/buffering images from internet?

Post by sturgis » Thu Mar 14, 2013 3:47 pm

When you use load on mobile it loads the images but does NOT cache them. (unless this has changed recently? ) on desktop it does indeed cache, mobile it does not. Someone update me if this has changed.


So, when you use load, you get the nice benefits of async but no huge memory fill and no need to use unload.

What mark is saying is that when the load is complete you should have a callback message set up to handle the data that has just come in. It will be in one of the parameters that are passed with the callback message.

Put the data in the parameter into the image object in question.

At this point the image will be the size of the image from the URL. size the image how you want it, then and do as mark indicated to end up with a smaller size smaller memory usage image.

n9yty
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 52
Joined: Thu Feb 28, 2013 11:33 pm

Re: Resizing/caching/buffering images from internet?

Post by n9yty » Thu Mar 14, 2013 3:55 pm

Okay, so...

I created a placeholder image object.
When I parse the HTML and find an image tag, I do:

put URL {imageurl} into image "placeHolderImage"
-- although the image object is sized to 75 and locked, I set size here in case it matters
-- to get imageData sized properly
set the width of image "placeHolderImage" to 75
set the height of image "placeHolderImage" to 75
put the imageData of image "placeHolderImage" into myGridData[myIndex]["colImage"]
put empty into image "placeHolderImage"

Then, in the behavior script for the row of the data grid:
set the text of image "Image" to pDataArray["colImage"]

That gives me blank images. I also tried:
set the imageData of image "Image" to pDataArray["colImage"]

This gives bizarre behavior... some images are blank. A few have images but the images in those rows change as you scroll the list up and down.

I'm clearly missing something important here... :)

Mark
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 5150
Joined: Thu Feb 23, 2006 9:24 pm
Contact:

Re: Resizing/caching/buffering images from internet?

Post by Mark » Thu Mar 14, 2013 4:07 pm

Hi,

You're confusing text and image data. Text is the picture data from a picture file, like JPEG or PNG. Imagedata is a LiveCode-specific format and is not the same as picture data.

When you set or get the text, you use picture data. Putting an URL into an image control is the same as setting the text of the image control.

Once you get the imagedata of an image control, the only way to display this imagedata again is by setting the imagedata property. If you set the text of an image control to imagedata, you get a corrupt image (and sometimes a crash).

You should not set the lockLoc of an image to true before you set the text of the image. You need to change the size of an image and set the lockLoc after setting the text.

Before you set the imagedata of an image, you need to make sure that the width and height of the image are correct. This is exactly the opposite of when you set the text.

I hope this helps.

Best,

Mark
The biggest LiveCode group on Facebook: https://www.facebook.com/groups/livecode.developers
The book "Programming LiveCode for the Real Beginner"! Get it here! http://tinyurl.com/book-livecode

n9yty
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 52
Joined: Thu Feb 28, 2013 11:33 pm

Re: Resizing/caching/buffering images from internet?

Post by n9yty » Thu Mar 14, 2013 4:15 pm

Mark wrote:You're confusing text and image data. Text is the picture data from a picture file, like JPEG or PNG. Imagedata is a LiveCode-specific format and is not the same as picture data.
I have tried both, and couldn't get it to work either way.
Mark wrote:Once you get the imagedata of an image control, the only way to display this imagedata again is by setting the imagedata property. If you set the text of an image control to imagedata, you get a corrupt image (and sometimes a crash).
But it didn't work when I grabbed the imageData of the placeholder and tried to set that in the data grid row behavior script.
Mark wrote:You should not set the lockLoc of an image to true before you set the text of the image. You need to change the size of an image and set the lockLoc after setting the text.
It was locked in the editor, I don't think that is the same thing as lockLoc, is it? I did not set lockLoc in my scripts.
Mark wrote:Before you set the imagedata of an image, you need to make sure that the width and height of the image are correct. This is exactly the opposite of when you set the text.
The image in the data grid is 75 x 75 which is what I set the placeholder to before I grabbed the imageData.

I really appreciate all the help, but it looks like short of finding a working example I don't know that I'll get this sorted out because everything I try keeps falling over. Any explanation for the odd behavior where the image data in the data grid CHANGES as you move the rows up and down in the list scroller? That just blows my mind.

Just to be clear, here is the actual code producing this:

Code: Select all

put URL imageURL into image "webImage" of card "Images" of stack "Resources"
set the width of image "webImage" of card "Images" of stack "Resources" to 75
set the height of image "webImage" of card "Images" of stack "Resources" to 75
put the imageData of image "webImage" of card "Images" of stack "Resources" into storyGridData[storyCount]["colImage"]
put empty into image "webImage" of card "Images" of stack "Resources"
Then in the row behavior script in FillInData:

Code: Select all

set the imageData of image "Image" to pDataArray["colImage"]
EDIT: The last bit above in the behavior script should be:

Code: Select all

set the imageData of image "Image" of me to pDataArray["colImage"]
That seems to have sorted the image changing problem. Small oversight with big problem. :) Now back to the resizing issue, but with this introduced bug out of the way it should be easier. :)

Simon
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 3901
Joined: Sat Mar 24, 2007 2:54 am

Re: Resizing/caching/buffering images from internet?

Post by Simon » Thu Mar 14, 2013 8:20 pm

I'm late in this conversation but here is the lesson for image resizing:
http://lessons.runrev.com/s/lessons/m/4 ... nail-image
crazy cool line:
set the imagedata of image tImageName to the imagedata of image tImageName

Simon
I used to be a newbie but then I learned how to spell teh correctly and now I'm a noob!

n9yty
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 52
Joined: Thu Feb 28, 2013 11:33 pm

Re: Resizing/caching/buffering images from internet?

Post by n9yty » Fri Mar 15, 2013 1:41 am

Well, it is working fine in LiveCode, but when standalone (both on Mac and Android) the images are messed up, my guess is the dimensions are off somehow so that the raw imageData I'm pasting back in is not lining up right for the destination container. But why only in standalone and not in the IDE? And both image objects are set to the same dimensions of 75x75, so I wouldn't have expected a mismatch. And I did that wonderful put imageData of image "image" into imageData of image "image" thing to lock in the resize first before I copied the imageData for the data grid... :)

And I thought I had it... LoL But I will say that, even though the images don't display right, the moving between cards is far more responsive.

Mark
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 5150
Joined: Thu Feb 23, 2006 9:24 pm
Contact:

Re: Resizing/caching/buffering images from internet?

Post by Mark » Fri Mar 15, 2013 1:48 am

Hi,

Can you explain very exactly what "messed up" means?

Are you saving any files anywhere?

Best,

Mark
The biggest LiveCode group on Facebook: https://www.facebook.com/groups/livecode.developers
The book "Programming LiveCode for the Real Beginner"! Get it here! http://tinyurl.com/book-livecode

n9yty
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 52
Joined: Thu Feb 28, 2013 11:33 pm

Re: Resizing/caching/buffering images from internet?

Post by n9yty » Fri Mar 15, 2013 2:27 am

Messed up as in the image is garbled, looks like the data was "slanted" but not exactly consistent. I went back through the properties for both the placeholder/resizing image as well as the image in the data grid and something that I checked or unchecked has resolved the problem. I suppose it would be more useful if I knew *what* it was, but at least it is working now. I am not saving the images as of yet, that will come next.

Looking back, the checkboxes I was messing with were "Don't Dither", "Preload into Memory", and the image quality drop down, at least it is likely one of those three.

Mark
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 5150
Joined: Thu Feb 23, 2006 9:24 pm
Contact:

Re: Resizing/caching/buffering images from internet?

Post by Mark » Fri Mar 15, 2013 2:45 am

So, it is solved now? I wish I knew what caused the problem :-)

Mark
The biggest LiveCode group on Facebook: https://www.facebook.com/groups/livecode.developers
The book "Programming LiveCode for the Real Beginner"! Get it here! http://tinyurl.com/book-livecode

Post Reply