Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Cleancode : load & scale image 2

Status
Not open for further replies.

Leozack

MIS
Oct 25, 2002
867
GB
This is gonna sound so primative since I've been dabling in image preloaders and galleries and all sorts now but what I really wanted was a way, in as little code as possible (just a short function then) to make the process of loading an image into an MC eg

var mc = this.createEmptyMovieClip("holder", 10);
mc.loadMovie("images/image1.jpg");

but to get flash to wait and find the size of the image and adjust it to fit the MC first rather than auto adjusting the MC to fit it.

I know you can hack your way to doing this with ondata and onload and stuff but I'm looking for the cleanest simplest way to do it with --- Flash MX 6 ---.

Thanks for any examples. I'll continue trawling for how I'm sure I saw it done relatively simply before somewhere

_________________________________
Leozack
Code:
MakeUniverse($infinity,1,42);
 
Code:
var mc = this.createEmptyMovieClip("holder", 10);
// Set the container's alpha to 0...
mc._alpha = 0;
mc.loadMovie("images/image1.jpg");
// Some preloading code...
this.onEnterFrame = function(){
    if(mc.getBytesLoaded() >= mc.getBytesTotal() && mc.getBytesLoaded() > 0){
        // Picture is fully loaded...
        // Scaling and resizing code...
        mc._alpha = 100;
        delete this.onEnterFrame;
    }
};

Or you can basically do the same with the movieClipLoader's onLoadInit handler...



Regards. FLASH HELP - OPENED FOR BUSINESS!
TO GET YOUR OWN FREE WEBSITE HOSTING
 
Thanks mate, thought movieClipLoader isn't in FMX6 it's in F7 I read on adobe?

Anyway I added the following scaling code and got mixed results.
Code:
	// Set the container's alpha to 0...
	imgholderMC._alpha = 0;
	imgholderMC.loadMovie("images/image1.jpg");
	// Some preloading code...
	imgholderMC.onEnterFrame = function(){
		if(imgholderMC.getBytesLoaded() >= imgholderMC.getBytesTotal() && imgholderMC.getBytesLoaded() > 0){
			// Picture is fully loaded...
			// Scaling and resizing code...
			if (imgholderMC._width > imgholderMC._height) {
				imgholderMC._xscale = imgholderMC._yscale = (imgWidth/imgholderMC._width) * 100;
			} else {
				imgholderMC._yscale = imgholderMC._xscale = (imgHeight/imgholderMC._height) * 100;
			}
			
			imgholderMC._alpha = 100;
			delete imgholderMC.onEnterFrame;
		}
	};
Though I've just noticed I haven't made it center there.

I thought it was time I got together with my other example projects to try to pull the whole thing together (image scaling & centering, stage runtime setup then user-scalable, creating textboxes etc) but the end result was as I'd expected a culmination of the failiures stopping me from getting onto the code I wanted to be doing all along which is depressing.

Here's an example project where the stage design then stage resize is all working fine
Here's the one I just knocked up where things aren't working.
And here's the 2 images I'm using just for now

I've threaded too much already! See what you think :/

_________________________________
Leozack
Code:
MakeUniverse($infinity,1,42);
 
Yeah I'm guessing despite the code being another clean attempt to combine it all and working in theory, the fact thiings like the textboxes just go double the size they should and so on mean you've had no luck either :( This bugs me so much cos I'm never getting to the point where I can actually code from a working base despite the code for the base working ok in seperate bits :/

_________________________________
Leozack
Code:
MakeUniverse($infinity,1,42);
 
Ok I've finally sorted the framework and got it all working and way over customisable by the user as usual.

However, I'm still having problems with the basic image loading. What's the problem with the following function, that gets get an MC container and a filename to load in? :( the trace just gives 0 / 0 repeatedly forever and the image appears loaded and I can't operate on the clip to resize it etc :(
Code:
function LoadImage(clip, filename) {
	// Set the container's alpha to 0...
	//trace(clip);
	clip._alpha = 0;
	clip.loadMovie(filename);
	// Some preloading code...
	clip.onEnterFrame = function(){
		trace(clip.getBytesLoaded()+" / "+clip.getBytesTotal());
		if(clip.getBytesLoaded() >= clip.getBytesTotal() && clip.getBytesLoaded() > 0){
			// Picture is fully loaded...
			// Scaling and resizing code...
			clip._alpha = 100;
			delete clip.onEnterFrame;
		}
	};

_________________________________
Leozack
Code:
MakeUniverse($infinity,1,42);
 
And yes sorry I missed the trailing }; in there, that's not the problem ;)

_________________________________
Leozack
Code:
MakeUniverse($infinity,1,42);
 
Don't know where you got the idea of setting the onEnterFrame on the container clip itself, but it was wrong...

Next, my bad in this line...
Should of been > 4... (size of the empty container clip)

if(mc.getBytesLoaded() >= mc.getBytesTotal() && mc.getBytesLoaded() > 4){...

In any case, the following works fine... And yes, I did add the missing trailing }; in there...

Code:
function LoadImage(clip, filename) {
    // Set the container's alpha to 0...
    //trace(clip);
    clip._alpha = 0;
    clip.loadMovie(filename);
    // Some preloading code...
    onEnterFrame = function(){ // or this.onEnterFrame works as well...
        trace(clip.getBytesLoaded()+" / "+clip.getBytesTotal());
        if(clip.getBytesLoaded() >= clip.getBytesTotal() && clip.getBytesLoaded() > 4){
            // Picture is fully loaded...
            // Scaling and resizing code...
            clip._alpha = 100;
            delete onEnterFrame; // or this.onEnterFrame works as well...
        }
    };
};
filename="some.jpg"; // or some .swf
LoadImage(clip, filename);

Regards. FLASH HELP - OPENED FOR BUSINESS!
TO GET YOUR OWN FREE WEBSITE HOSTING
 
I got the idea by thinking maybe it'd work on the clip, guess not.

Eitherway I've now perfected the whole loading, scaling, and centering and it seems fairly bulletproof, and upscales aswell as downscales.

Code:
function LoadImage(clip, maxWidth, maxHeight, filename) {
    // Set the clip's alpha to 0...
    clip._alpha = 0;
    clip.loadMovie(filename);
    // Some preloading code...
    onEnterFrame = function(){ // or this.onEnterFrame works as well...
        if(clip.getBytesLoaded() >= clip.getBytesTotal() && clip.getBytesLoaded() > 4){
            // Scale
			scaleW = (maxWidth / clip._width);
			scaleH = (maxHeight / clip._height);
			if (scaleH >= scaleW) { newScale = scaleW; }
			else { newScale = scaleH; }
			clip._width = clip._width * newScale;
			clip._height = clip._height * newScale;
			// Center
			if (clip._width < maxWidth) { clip._x = (maxWidth/2) - (clip._width/2); }
			if (clip._height < maxHeight) { clip._y = (maxHeight/2) - (clip._height/2); }
			// Show
            clip._alpha = 100;
            delete onEnterFrame; // or this.onEnterFrame works as well...
        }
    };
};

_________________________________
Leozack
Code:
MakeUniverse($infinity,1,42);
 
Haha I love your style

However - as with most flash things I knock up in a blank file until it's all working, I've put it into my main project and it's not playing ball at all. So I'm not out of the wood just yet, though I'm guessing it's more problems to do with clips adopting scales from parents or something meaning calculations that should work (like those above) give bad results. That's the sort of thing that held me up until today when I realised the library clips I was resizing initially were screwing all child textboxes I made using the correct sizes due to scales already imposed on them.

Right now though I'm back to troubleshooting why the image isn't scaling in properly in my actual app :/

_________________________________
Leozack
Code:
MakeUniverse($infinity,1,42);
 
Ah - my bad - I had my image holder clip named "image_mc" in the createEmptyMovieClip call (I'm never using those handles though, always using the variables the result is assigned to instead ever since getting exambles off you and ken) aswell as that of the image holder background clip. Changed one of them and no more duplicate names, no more scrolling of the onenterframe event never triggering the onload correctly, and all is well with the world. Have a star you brave guy! :)

_________________________________
Leozack
Code:
MakeUniverse($infinity,1,42);
 
Guess what - new oddities come out of the woodwork to hold me up!
I've made the borders size 10 to highlight the issue.

1 - The borders seem to goto the topleft of the box you're drawing, rather than stay centralised on the lines, or preferably inside the area you're drawing. If there's no way to change this I'll have to use the borderSize variable in all sorts of places to offset and shrink things :( I'm using the following code.
Code:
function GradientBox(clip, colour1, colour2, alpha, x, y, w, h, borderWidth, borderColour, borderAlpha){
	fillType = "linear";
	colours = [colour1, colour2];
	alphas = [alpha, alpha];
	ratios = [0, 255];
	matrix = {matrixType:"box", x:x, y:y, w:w, h:h, r:90/180*Math.PI};
	clip.lineStyle(borderWidth, borderColour, borderAlpha);
	clip.moveTo(x, y);
	clip.beginGradientFill(fillType, colours, alphas, ratios, matrix);
	clip.lineTo(w, y);
	clip.lineTo(w, h);
	clip.lineTo(x, h);
	clip.lineTo(x, y);
	clip.endFill();
};

2 - The image you load (and now I check that image, the text also) has to compensate for the border size to not end up going over the top of the borders (the filled bordered boxes are under the text/image layers). I modified my image scaling/centering code with what I thought is logical alterations using borderSize variables - shrink the area you're scaling into by bordersize*2, and offset the centering by bordersize. But no luck :(
Code:
scaleW = ((maxWidth - (bordersize * 2)) / clip._width);
scaleH = ((maxHeight - (bordersize * 2)) / clip._height);
if (scaleH >= scaleW) { newScale = scaleW; }
else { newScale = scaleH; }
clip._width = clip._width * newScale;
clip._height = clip._height * newScale;
// Center
if (clip._width < maxWidth) { clip._x = bordersize + (maxWidth/2) - (clip._width/2); }
if (clip._height < maxHeight) { clip._y = bordersize + (maxHeight/2) - (clip._height/2); }
All thoughts welcome :/

_________________________________
Leozack
Code:
MakeUniverse($infinity,1,42);
 
Further testing reveals drawing lines and filled boxes should have the fat size10 borders centered on the line/box they're drawn. So ... why in my project do they end up being up and left like this? :(
Exactly the same code as my lines.png example above - using my GradientBox function on a movieclip that was positioned to 150,150 where those lines were, yet in lines.png it's fine x_x

_________________________________
Leozack
Code:
MakeUniverse($infinity,1,42);
 
After more testing and recalculations I've got it all working smoothly. For those scoring at home, this is the image loading script which now compensates for whatever border thickness you give it and will compensate for the fact flash is drawing a border of that thickness around the area size you want to fit the image into. Centering appears to be correct also.
Code:
function LoadImage(clip, maxWidth, maxHeight, bordersize, filename) {
    clip._alpha = 0;
    clip.loadMovie(filename);
    onEnterFrame = function() {
        if(clip.getBytesLoaded() >= clip.getBytesTotal() && clip.getBytesLoaded() > 4){
            // Scale
			scaleW = ((maxWidth - (bordersize * 2)) / clip._width);
			scaleH = ((maxHeight - (bordersize * 2)) / clip._height);
			if (scaleH >= scaleW) { newScale = scaleW; }
			else { newScale = scaleH; }
			clip._width = clip._width * newScale;
			clip._height = clip._height * newScale;
			// Center
			if (clip._width < maxWidth) { clip._x = (maxWidth/2) - (clip._width/2); }
			if (clip._height < maxHeight) { clip._y = (maxHeight/2) - (clip._height/2); }
			// Show
            clip._alpha = 100;
            delete onEnterFrame;
        }
    };
};
When drawing the other boxes and text I compensate for the borders also eg
Code:
function GradientBox(clip, colour1, colour2, alpha, x, y, w, h, borderWidth, borderColour, borderAlpha){
// Using my gradientbox function, I compensate for the centered
// thickness flash uses for boders with calls like this
GradientBox(imgMC,BgColour1,BgColour2,BgAplha,Border/2,Border/2,imgWidth-(Border/2),imgHeight-(Border/2),Border,BorderColour,BorderAplha);

// And for text to stay within the bordered box :
// Move text up proportionately to strip top leading
var	Leading = titleTxtSize/6;
titleMC.createTextField("title_text",LayerNum,titleBorderWidth,titleBorderWidth-Leading,imgWidth-(titleBorderWidth*2),Leading+titleHeight-(titleBorderWidth*2));

// But if I just want the text to be kept to 1 line, not autosized,
// but not needing to be contained within the box like above because
// it'll never get to the bottom, then using this formula :

// Move text up proportionately to strip top leading
// Extent height of text by Leading + textsize converted from
// points to pixels (points * 1.33333)
var	Leading = imgTxtSize/6;
imgMC.createTextField("img_title",LayerNum,imgBorderWidth,imgBorderWidth-Leading,imgWidth-(imgBorderWidth*2),Leading+(Math.floor(imgTxtSize*1.4)));

_________________________________
Leozack
Code:
MakeUniverse($infinity,1,42);
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top