Fijate si te sirve para implementar o como idea (
Aquí un ejemplo online que funciona para navegadores que soportan canvas y por tanto nos ahorramos GD -está indicado en el código el lugar donde debería implementarse la solución del lado del servidor para los navegadores que no soportan canvas-):
Código PHP:
<!DOCTYPE HTML>
<htmL>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Documento sin título</title>
<script type="text/javascript">
/*---- funciones auxiliares---*/
//DOMReady
var DR=function(f){
if(document.addEventListener){
var func=function(){f();document.removeEventListener('DOMContentLoaded',func,false);}
document.addEventListener('DOMContentLoaded',func,false);
}else{
function r(f){/in/.test(document.readyState)?setTimeout(function(){r(f);},9):f();};
r(f);
}
}
function clearSelection() {
if(window.permSel)return;
var sel ;
if(document.selection && document.selection.empty){
try{document.selection.empty() ;}catch(err){}
} else if(window.getSelection) {
sel=window.getSelection();
if(sel && sel.removeAllRanges)
sel.removeAllRanges() ;
}
}
function cancelEvent(e){
if(e && e.preventDefault)
e.preventDefault();
else if(window.event)
window.event.returnValue=false;
}
/*---- cropeo---*/
var crop=(
function(){
var cur='';
var coords={x:0,y:0};
var coords2={x:0,y:0};
var origen={x:0,y:0};
var origen2={x:0,y:0};
var renderizar=0;
var recorte=0;
var f=document.createDocumentFragment();
var l=document.createElement('div');
var r=document.createElement('div');
var t=document.createElement('div');
var b=document.createElement('div');
var over=document.createElement('div');
l.style.borderLeft=r.style.borderLeft='1px dashed white';
t.style.borderBottom=b.style.borderBottom='1px dashed white';
over.style.position=l.style.position=r.style.position=t.style.position=b.style.position='absolute';
over.style.top='-15000px';
over.style.zIndex=100;
l.style.width=r.style.width=t.style.width=b.style.width=l.style.height=r.style.height=t.style.height=b.style.height=0;
f.appendChild(l);
f.appendChild(r);
f.appendChild(t);
f.appendChild(b);
over.appendChild(f);
DR(function(){
document.body.appendChild(over);
});
var mp={
iniciar:function(o){
crop.target=o;
var pos=this.getElementPosition(o);
var w=o.width || o.offsetWidth || 0;
var h=o.height || o.offsetHeight || 0;
over.style.width=w+'px';
over.style.height=h+'px';
over.style.top=pos.top+'px';
over.style.background='url('+o.src+')';
over.style.left=pos.left+'px';
this.addEvent('mousemove',this.setCoord,over);
this.addEvent('mousedown',this.setOrigen,over);
this.addEvent('mouseup',function(){renderizar=0;over.style.cursor='default';},over);
over.style.cursor='default';
},
render:function(){
if(renderizar){
if((coords.y-origen.y)<0){
origen2.y=coords.y+3;
coords2.y=origen.y;
cur='n';
}else{
origen2.y=origen.y;
coords2.y=coords.y-3;
cur='s';
}
if((coords.x-origen.x)<0){
origen2.x=coords.x+3;
coords2.x=origen.x;
cur+='w';
}else{
origen2.x=origen.x;
coords2.x=coords.x-3;
cur+='e';
}
over.style.cursor=cur+'-resize';
l.style.top=t.style.top=r.style.top=origen2.y+'px';
l.style.left=t.style.left=b.style.left=origen2.x+'px';
r.style.left=coords2.x+'px';
b.style.top=coords2.y+'px';
l.style.height=r.style.height=Math.abs(coords2.y-origen2.y)+'px';
t.style.width=b.style.width=Math.abs(coords2.x-origen2.x)+'px';
t.style.height=b.style.height=l.style.width=r.style.width=0;
if(parseInt(l.style.height)<5 || parseInt(t.style.width)<5){
t.style.visibility=l.style.visibility=r.style.visibility=b.style.visibility='hidden';
recorte=0;
}else{
t.style.visibility=l.style.visibility=r.style.visibility=b.style.visibility='visible';
recorte=1;
}
}
},
setOrigen:function(x){
cancelEvent(x);
var ev=x || event;
var o=ev.target || ev.srcElement;
if(o!=over)return false;
l.style.width=r.style.width=t.style.width=b.style.width=l.style.height=r.style.height=t.style.height=b.style.height=0;
l.style.left=r.style.left=b.style.left=t.style.left=coords.x+'px';
l.style.top=r.style.top=b.style.top=t.style.top=coords.y+'px';
origen={x:coords.x,y:coords.y};
renderizar=1;
recorte=0;
over.style.cursor='default';
},
setCoord:function(x){
cancelEvent(x);
clearSelection();
var ev=x || event;
var o=ev.target || ev.srcElement;
var posX=ev.layerX || ev.offsetX || 0;
var posY=ev.layerY || ev.offsetY || 0;
coords={x:posX,y:posY};
if(o==over)
mp.render();
},
addEvent: function(type, fn,o ) {
if ( o.addEventListener ) {
o.addEventListener( type, fn, false );
} else if(o.attachEvent){
var O=o;
var f= function(){fn.call(O,window.event);}
o.attachEvent( 'on'+type, f);
o[fn.toString()+type]=f;
}else{
o['on'+type]=fn;
}
var ev={_obj:this,_evType:type,_fn:fn};
window.EvRegister=window.EvRegister || [];
window.EvRegister.push(ev);
},
getElementPosition:function(o) {
var offsetTrail = o;
var offsetLeft = 0;
var offsetTop = 0;
while (offsetTrail) {
offsetLeft += offsetTrail.offsetLeft;
offsetTop += offsetTrail.offsetTop;
offsetTrail = offsetTrail.offsetParent;
}
return {left:offsetLeft, top:offsetTop};
}
};
return {
setTarget:function(id){
if(!document.getElementById(id)){
throw new Error('El elemento no existe o no posee atributo id');
}else if(document.getElementById(id).nodeName.toLowerCase()!='img'){
throw new Error('El elemento no es una imagen');
}else{
mp.iniciar(document.getElementById(id));
}
},
getCoords:function(){
if(recorte)
return {xo:origen2.x,yo:origen2.y,xd:coords2.x,yd:coords2.y}
return 0;
}
}
})();
DR(
function(){
crop.setTarget('arw');//seteamos la imagen a cropear indicando su id
}
);
function cropear(){
/*---obtenemos las coordenadas del cropeo:---*/
var recorte=crop.getCoords();
if(!recorte)return false;
/*--- si canvas está soportado le ahorramos trabajo al servidor ---*/
if(document.createElement('canvas').getContext){
var canvas=document.createElement('canvas');
canvas.width=recorte.xd-recorte.xo;
canvas.height=recorte.yd-recorte.yo;
var ctx=canvas.getContext('2d');
ctx.drawImage(crop.target, recorte.xo, recorte.yo, canvas.width, canvas.height, 0, 0, canvas.width, canvas.height);
var src=canvas.toDataURL();
}else{
//recortar en servidor
}
/*--- opcional: mostramos la imagen---*/
var im=document.createElement('img');
im.src=src;
document.body.appendChild(im);
}
</script>
</head>
<body>
<img id="arw" src="arwen.jpg" width="500" height="350">
<form action="" method="get">
<input onClick="cropear()" id="gc" name="" type="button" value="cropear">
</form>
</body>
</html>
He agregado alguna mejora