...

View Full Version : Crop an image in Flash



beedie
05-31-2008, 02:14 PM
I have images that the user is cropping.
At the moment I have a great javascript cropper that lets you drag over the image creating the selected area to crop. Holding shift keeps it square.
What I need to do is only have a circular cropping area(visually). It doesn't matter if it crops as a square but the user needs to see the circular area only. Essentailly the circle fits in a square touching all 4 sides. My server side script will create the circle.
Masking the corner areas maybe??
Any thoughts,suggestions much appreciated.
Is this something for Flash?

gnomeontherun
06-01-2008, 09:42 PM
I think your current JS cropper could be easily modified to be a circle. I don't think Flash is good for this, and it is actually the server side scripting that creates the new image. My idea is that you can have someone draw a box to get the dimensions, and then instead of having the script crop it as a square make sure it is just a circle. It could be done in Flash I'm sure, but in this case I would avoid it since you already have something very similar working with JS.

beedie
06-02-2008, 09:50 AM
I am willing to try flash.
At the moment it does what you say.
User drags a square and the server side handles making the circle.
What i am looking for is to somehow mask the square as a circle so the user sees what they will get. Happy to keep all the code. It is merely cosmetic.
I am using this cropper:

http://www.defusion.org.uk/code/javascript-image-cropper-ui-using-prototype-scriptaculous
basic

It is great so if I can keep it that would help.
Any other thoughts most welcome.

gnomeontherun
06-02-2008, 05:16 PM
Ahh ok, you didn't mention that the current script made a circle. It led me the believe it was a rectangle, but I understand now.

Well in both situations, you need to be able to find the dimensions of the user created circle. There are a few things that probably make doing it in Flash a little bit different.

Here is the idea I have about how to go about it, but its several steps and I think if you are really interested in learning some Flash you can take these steps and put them together.

1) You need to be able to upload an image into Flash. The image must be loaded on to the stage into a movieClip. Search for tutorials on uploading images into Flash.

2) You need to allow the user to drag and create a circle. Search for tutorials on how to allow users to drag and place shapes on the stage. (http://www.codingforums.com/showthread.php?t=139375 also has some discussion on drag and drop for shapes) - You may wish to add effects so that everything else is slightly faded out, which you will have to look into masking effects.

3) You need to grab the location of the shape and find its dimensions. This is just asking AS for some of the shapes properties, like _w _h etc.

4) You will have to send the properties to the same script (probably) that you are using now.

If you tackle this step by step I'll help you code the individual parts if you post questions here. It was hard to find any tutorials for this due to everything being crop circles (aliens). Make sure each part works before trying the next, because if not then testing will be very hard. I also only know AS2 right now, so if you are planning on using AS3 it might not be as easy to find tutorials and to get help from me.

beedie
06-03-2008, 10:27 AM
Thanks a lot for your suggestions.
I have found a way to load an image to the stage.
It will need some adjustments:

imgbtn1.onRelease = function() {
infoField._visible = true;
startLoading("picture1.jpg");
};

function startLoading(whichImage) {
loadMovie(whichImage, "imageLoader");
_root.onEnterFrame = function() {
infoLoaded = imageLoader.getBytesLoaded();
infoTotal = imageLoader.getBytesTotal();
percentage = Math.floor(infoLoaded/infoTotal*100);
infoField.text = percentage+"%";
if (percentage>=100) {
delete this.onEnterFrame;
infoField._visible = false;
}
};
}
Just need to change the onrelease button to when page loads. No button needed for my script. I will then just put the uploaded image in the same location with the same name each time. I imagine this will work if there aren't many users at the same time. Best would be if I could pass a variable with the file name so it could be unique.
Next is the dragging a circle and getting it's location and size from ActionScript. Ideally the info from the AS would be for a square around the circle. Then my script needs no change. Any clues? I have no AS experience but it looks quite straightforward as I am familiar with PHP and a bit of JS.

beedie
06-03-2008, 05:13 PM
Just adding that this line was all I needed for the loading the photo

loadMovie("picture1.jpg", imageLoader);

Simple. Now the question. Is it possible to make "picture.jpg" a variable that is set in PHP and passed to the swf file from the upload script? Seems like it must be. Is there a $_GET['image'] type option in Flash?

gnomeontherun
06-03-2008, 06:10 PM
You have to load the variables from the upload script. Flash is different because it has to load on the clients computer before being able to execute any code, so any code you put on the first line will run as soon as the flash document has loaded. Here is a tutorial about loading the data.

http://www.flash-db.com/Tutorials/loading/loadingData.php

beedie
06-04-2008, 06:24 AM
Those tutorials are very helpful.
I have my uploaded image from PHP to the SWF.
I also have the draggable mask.
Now I am not sure whether I am going to be able to make the circular crop mask resizable.

I don't see anything like that in my searches.

gnomeontherun
06-04-2008, 08:30 AM
I would suggest having the shape made initially by dragging. Theres a post above I linked to with some examples of its use.

Here is a link to a tutorial about how to make a circle with AS: http://www.pixelwit.com/blog/2007/06/29/basic-circle-drawing-actionscript/
Problem is that it doesn't do it on a click/drag combo. I can't seem to find a good tut on that right now. Maybe we'll have to tackle that one.

Do you have a link to show what you have?

beedie
06-04-2008, 10:59 AM
The link you gave there draws a circle but I don't think it lets the user do it.
Below is a script with the crop area already loaded but resizeable.

http://flashrocket.worldoptimizer.com/article/23/flash-based-cropping-tool-released-lgpl
download the Flash Based cropping tool vers 1.
The .fla in there is almost what I am looking for.
The problem is seeing which bits I need due to lack of AS knowledge. If I simply turn their mask into a circle and make resizing a square always I would be done.
My own script is still local so I can't show yet.
When it is done I'll happily put the whole thing here with a link to the live site.

gnomeontherun
06-05-2008, 09:14 PM
I loaded that script and thought it had a few strange behaviors. I could only resize along the X axis, and could not change the height of the crop window. I am in favor of making something new instead.

I'm feeling adventurous and willing to tackle some coding on this.

This code will make a circle and you can drag it to the size you wish. I think this might be a very helpful piece. This will allow you to create a a movieclip which can be used as the mask for your cropping.


this.onMouseDown = function() {
startX = this._xmouse;
startY = this._ymouse;
isDrawing = true;
this.onMouseMove = function() {
if (isDrawing == true) {
drawing_mc.clear();
this.createEmptyMovieClip("drawing_mc",100);
fillCircle(drawing_mc, startX + ((this._xmouse - startX) / 2), startY + ((this._ymouse - startY) / 2), getRadius(startX, startY, this._xmouse, this._ymouse), "#0000000");
}
}
}

this.onMouseUp = function() {
isDrawing = false;
}

function getRadius(ax, ay, bx, by) {
var radius = (Math.sqrt(((ax - bx) * (ax - bx)) + ((ay - by) * (ay - by)))) / 2;
return radius;

}

function fillCircle(obj, X, Y, r, color) {
obj.lineStyle(.25, color);
obj.beginFill(color, 100);
obj.moveTo(X+r, Y)
for (i=0; i<100; i++) {
ang = i * (2*Math.PI/100)
xpos = r*Math.cos(ang)+X;
ypos = r*Math.sin(ang)+Y;
obj.lineTo(xpos, ypos)
}
obj.endFill();
}

beedie
06-06-2008, 02:57 PM
So this is my code that gets my image from the upload to the holder_mc.
I put your code below it and got my black circle. I made an instance of drawing_mc and a layer called drawing. is there a way to get your circle to be draggable if the user clicks on it?


myData = new LoadVars()
myData.load("imagecode.txt")
myData.onLoad = function(succes){
if(succes){
holder_mc.loadMovie(this.Image)
} else trace("Error loading data")
} ;

Also I tried to do a onMouseDown to change the opacity of the Image. Not sure about the syntax.

gnomeontherun
06-06-2008, 09:08 PM
Yes, we can do a hit test to see if the user is clicking on the circle, and if so start to drag instead of making a new circle. I got that to work, it was getting a new circle that I struggled with. I ended up just putting a button at the bottom that says Clear. Here is code


myData = new LoadVars()
myData.load("imagecode.txt")
myData.onLoad = function(succes){
if(succes){
holder_mc.loadMovie(this.Image)
} else trace("Error loading data")
};

this.onMouseDown = function() {
if (this.hitTest(drawing_mc)) {
startDrag(drawing_mc, false);
isDragging = true;
}
else {
startX = this._xmouse;
startY = this._ymouse;
isDrawing = true;
this.onMouseMove = function() {
if (isDrawing == true) {
drawing_mc.clear();
radius = getRadius(startX, startY, this._xmouse, this._ymouse);
this.createEmptyMovieClip("drawing_mc",100);
fillCircle(drawing_mc, startX + ((this._xmouse - startX) / 2), startY + ((this._ymouse - startY) / 2), radius, "#0000000");
drawing_mc._width = radius*2;
drawing_mc._height = radius*2;
}
}
}
}

clearbtn.onRelease = function() {
drawing_mc.clear();
}

this.onMouseUp = function() {
isDrawing = false;
if (isDragging == true) {
drawing_mc.stopDrag();
isDragging = false;
}
}

function getRadius(ax, ay, bx, by) {
var radius = (Math.sqrt(((ax - bx) * (ax - bx)) + ((ay - by) * (ay - by)))) / 2;
return radius;

}

function fillCircle(obj, X, Y, r, color) {
obj.lineStyle(.25, color);
obj.beginFill(color, 75);
obj.moveTo(X+r, Y)
for (i=0; i<100; i++) {
ang = i * (2*Math.PI/100)
xpos = r*Math.cos(ang)+X;
ypos = r*Math.sin(ang)+Y;
obj.lineTo(xpos, ypos)
}
obj.endFill();
}

beedie
06-07-2008, 08:20 AM
Thanks again.
Now I can just trace the various sizes and positions and send them to my php file.
I will post my final code soon.

beedie
06-08-2008, 12:40 PM
So here is my working action script.

myData = new LoadVars()
myData.load("imagecode.txt")
myData.onLoad = function(succes){
if(succes){
holder_mc.loadMovie(this.Image)
} else trace("Error loading data")
};

this.onMouseDown = function() {
if (this.hitTest(drawing_mc)) {
startDrag(drawing_mc, false);
isDragging = true;

}
else {
startX = this._xmouse;
startY = this._ymouse;
isDrawing = true;
this.onMouseMove = function() {
if (isDrawing == true) {
drawing_mc.clear();
radius = getRadius(startX, startY, this._xmouse, this._ymouse);
this.createEmptyMovieClip("drawing_mc",100);
fillCircle(drawing_mc, startX + ((this._xmouse - startX) / 2), startY + ((this._ymouse - startY) / 2), radius, "#0000000");
drawing_mc._width = radius*2;
drawing_mc._height = radius*2;
trace(startY);
my_x = this._xmouse;
my_y = this._ymouse;

}
}
}
}

clearbtn.onRelease = function() {
drawing_mc.clear();
}

this.onMouseUp = function() {
isDrawing = false;
if (isDragging == true) {
drawing_mc.stopDrag();
isDragging = false;

}
}

function getRadius(ax, ay, bx, by) {
var radius = (Math.sqrt(((ax - bx) * (ax - bx)) + ((ay - by) * (ay - by)))) / 2;
return radius;

}

function fillCircle(obj, X, Y, r, color) {
obj.lineStyle(2, color);
obj.beginFill(color, 8);
obj.moveTo(X+r, Y)
for (i=0; i<100; i++) {
ang = i * (2*Math.PI/100)
xpos = r*Math.cos(ang)+X;
ypos = r*Math.sin(ang)+Y;
obj.lineTo(xpos, ypos)
}
obj.endFill();
}



cropbtn.onPress = function () {
finalx = drawing_mc._x ;
finaly = drawing_mc._y ;
dragged_x = (my_x - startx);
dragged_y = (my_y - starty);

//to get x and y of top left corner of square around the circle
true_y = (starty - (radius - (dragged_y/2))) +finaly;

true_x = (startx - (radius - (dragged_x/2))) +finalx;
realwidth = (radius*2);
getURL ("cropper/tests/data2.php", "_self", "POST");
}
As my original PHP script needed the top left corner of a square that fits perfectly around the circle the true_x and true_y give me that point. diameter is the same as any side of the square so that gives me my width and height. All i needed to recreate the same circle on a png with a transparent background.
One more improvement comes to mind.
To make it possible to expand or contract the circle while dragging holding Shift for example.
Another thing would be to center the image in the holder_mc
Thanks again Jeremy for your help. I am getting addicted to Flash.

gnomeontherun
06-10-2008, 12:38 AM
You could probably write something that would change the scale of the drawing_mc, but then you would need to determine the hit location to be on the edge of the circle so it doesn't get mixed up with the dragging functions.

beedie
06-12-2008, 01:42 PM
So I have found a great class to cover all aspects this.
Download from here.
http://blog.greensock.com/transformmanageras2/
Easy to use. Even I can do it..
Just put the gs folder in the directory of the final swf file.


import gs.TransformManager;

var manager_obj = new TransformManager({targetObjects:[outline_mc], bounds:{xMin:0, xMax:600, yMin:0, yMax:600}, forceSelectionToFront:true, eventHandler:onAnyEvent});
manager_obj.addEventListener("move", onMove);
_root.manager_obj.constrainScale = outline_mc;
_root.manager_obj.lockRotation = outline_mc;

function onAnyEvent(event_obj:Object):Void {
trace("Action: "+event_obj.action+", MovieClip or TextField: "+event_obj.targetObject+", transformed?: "+event_obj.transformed);
}

function onMove(event_obj:Object):Void {
trace("Moved mc: "+event_obj.targetObject);
}
myData = new LoadVars()
myData.load("imagecode.txt")
myData.onLoad = function(succes){
if(succes){
holder_mc.loadMovie(this.Image)
} else trace("Error loading data")
}

cropBtn.onPress = function () {
var x_axis = outline_mc._x ;
var y_axis = outline_mc._y ;
//Being a circle this is enough to get both h and w.
realwidth = outline_mc._height;

//to get x and y of top left corner of square around the circle
true_x = x_axis - (realwidth/2);
true_y = y_axis - (realwidth/2);
getURL ("cropper/tests/data3.php", "_self", "POST");
}

my outline_mc is just a circle about 400 px with a border of 3 pixels. Fill is Alpha 5. Registration point in the center. holder_mc is an empty movie clip position at the top left of the movie.
Only thing to add is a preloader for the image.
Jeremy thanks for your help.
Anyone else please enjoy this script!

rountrjf
03-31-2009, 05:36 PM
I'm wanting to make an image clickable on my webpage editor I'm making and it then loads the image inside of the "TransformManager" and from there the user has a javascript dialog window with other photos available... then when they click on those photos it would add them to the TransformManager.

At the end it takes the final "image" of everything all together and crops it out and sends the "image" to the server as the fixed dimensions image that goes into the webpage predefined box.

Also I would like them to be able to drag the images beyond the border of the flash file(not necessarily keep them visible) just let them drag it anywhere.

Is this a possibility?

gnomeontherun
04-01-2009, 10:07 AM
Do you have a link or code?

I don't know of any way to have an image drag from inside of flash seemlessly outside. It would require some really fancy javascript.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum