Ver Mensaje Individual
  #1 (permalink)  
Antiguo 12/06/2015, 14:17
Avatar de Nemutagk
Nemutagk
Colaborador
 
Fecha de Ingreso: marzo-2004
Ubicación: México
Mensajes: 2.633
Antigüedad: 20 años, 1 mes
Puntos: 406
Calcular coordenadas sobre imagen redimencionada

Que tal compañeros, vengo a ustedes solicitando su valiosa ayuda, verán, tengo un problema, estoy generando una aplicación donde se subirá imágenes como avatares, pero como debe a ver un limite de tamañano lo que queremos es que si el usuario selecciona una imagen mayor al limite (160x160 pixeles) tengan opción para seleccionar un trozo de la imagen, hasta aquí todo bien, el problema se presenta cuando el usuario selecciona una imagen muy grande, por lo cual debo encajar la etiqueta img dentro del contenedor (un div), por lo cual la imagen esta a escala o x porcentaje mas chica de lo que es originalmente, y eh aquí el problema, intento calcular en base a las coordenadas selecionadas en la imagen mas pequeña para traspasar a la imagen original, pero, siempre obtengo un desface, y entre mas grande es la imagen mas grande el desface...

Todo se maneja en un formulario web y se maneja con Javascript, ajax y php, el formulario es el siguiente:

Código HTML:
Ver original
  1. <form method="post" action="/es/config/avatar" enctype="multipart/form-data" class="form-horizontal" id="avatar-form">
  2.         <div class="form-group">
  3.             <label class="label-control col-xs-10 col-sm-6" for="password">Contraseña actual</label>
  4.             <div class="col-xs-10 col-sm-6">
  5.                 <input type="password" value="" name="password" class="form-control" id="avatar-pass">
  6.             </div>
  7.         </div>
  8.         <div class="form-group">
  9.             <label class="label-control col-xs-10 col-sm-6" for="avatar">Imagen</label>
  10.             <div class="col-xs-10 col-sm-6">
  11.                 <button type="button" class="btn btn-primary" id="btn-avatar">ayanami_rei_neo...</button>
  12.                 <input type="file" name="avatar" class="form-control" id="avatar">
  13.             </div>
  14.         </div>
  15.         <div class="form-group">
  16.             <div class="col-xs-10 col-sm-6 col-sm-offset-6">
  17.                 <input type="submit" value="Cambiar" class="btn btn-primary">
  18.                 <input type="hidden" value="jNQfAJJ9SkGsiA2LLefDEL3W2laWc6T2RI7dDzRB" name="_token">
  19.                 <input type="hidden" value="0|0" id="cropcoordinates" name="cropcoordinates">
  20.                 <input type="hidden" value="160" id="cropsize" name="cropsize">
  21.                 <input type="hidden" value="0|0" id="fix" name="fix">
  22.             </div>
  23.         </div>
  24.     </form>

El contenedor de la imagen
Código HTML:
Ver original
  1. <div class="avatar-block">
  2.     <img class="avatar img-responsive" src="/img/avatars/avatar.png" id="preview">
  3.     <div id="divcut"></div>
  4. </div>

Y este es el código javascript que tengo
Código Javascript:
Ver original
  1. $(document).on('ready',function() {
  2.     $('#btn-avatar').on('click',function() {
  3.         $('#avatar').click();
  4.     });
  5.  
  6.     $('#avatar').on('change',function() {
  7.         var path = $(this).val();
  8.         var fileName = path.match(/[^\/\\]+$/);
  9.         var inputFile = this;
  10.  
  11.         var name = fileName[0].slice(0,15);
  12.         name += '...';
  13.         $('#btn-avatar').text(name);
  14.  
  15.         if (inputFile.files && inputFile.files[0]) {
  16.             var reader = new FileReader();
  17.  
  18.             reader.onload = function(e) {
  19.                 $('#preview').attr('src',e.target.result);
  20.                 setImage();
  21.             };
  22.  
  23.             reader.readAsDataURL(inputFile.files[0]);
  24.         }
  25.     });
  26.  
  27.     $('#avatar-form').on('submit',function() {
  28.         var form = this;
  29.         var fileInput = document.getElementById('avatar');
  30.         var file = fileInput.files[0];
  31.  
  32.         var formData = new FormData(form);
  33.         formData.append('password',$('#avatar-pass').val());
  34.         formData.append('avatar',file);
  35.         formData.append('cropcoordinates',$('#cropcoordinates').val());
  36.         formData.append('cropsize',$('#cropsize').val());
  37.         formData.append('fix',$('#fix').val());
  38.         formData.append('_token',$('input[name=_token]').val());
  39.  
  40.         $.ajax({
  41.             url: $(this).attr('action'),
  42.             data: formData,
  43.             contentType: false,
  44.             processData: false,
  45.             method: 'post',
  46.             cache: false
  47.         }).done(function(data) {
  48.             console.log('Enviado!');
  49.             //$('#preview').attr('src',data);
  50.         });
  51.  
  52.         return false;
  53.     });
  54. });
  55.  
  56. function setImage() {
  57.     $('#divcut').show();
  58.  
  59.     $('#fix').val('0|0');
  60.     $('#cropsize').val(160);
  61.     $('#cropcoordinates').val('0|0');
  62.  
  63.     var position = $('#divcut').position();
  64.  
  65.     var imgWidth = $('#preview').width();
  66.     var imgHeight = $('#preview').height();
  67.     console.log('tamaño imagen x:'+imgWidth+' y:'+imgHeight);
  68.  
  69.     var img = document.getElementById('preview');
  70.     var imgOrgWidth = img.naturalWidth;
  71.     var imgOrgHeight = img.naturalHeight;
  72.     console.log('tamaño original x:'+imgOrgWidth+' y:'+imgOrgHeight);
  73.  
  74.     var tmpFixTop = 0;
  75.     var tmpFixLeft = 0;
  76.     if (imgWidth < imgOrgWidth) {
  77.         var tmpFixTop = (imgWidth  / imgOrgWidth) * 100;
  78.         var tmpFixLeft = (imgHeight / imgOrgHeight) * 100;
  79.     }
  80.  
  81.     if (tmpFixTop > 0 || tmpFixLeft > 0) {
  82.         $('#fix').val(tmpFixTop+'|'+tmpFixLeft);
  83.         console.log('fix: '+tmpFixTop+'|'+tmpFixLeft);
  84.     }
  85.  
  86.     var imgPos = $('#preview').offset();
  87.     console.log('offset x:'+imgPos.left+' y:'+imgPos.top);
  88.     $('#divcut').offset({top:imgPos.top,left:imgPos.left});
  89.     var position = $('#divcut').position();
  90.  
  91.     $('#divcut').draggable({
  92.         containment: $('#preview'),
  93.         stop: function(event, ui) {
  94.             console.log('org coords x:'+ui.position.top+' y:'+ui.position.left);
  95.             var tmpTop = ui.position.top - position.top;
  96.             var tmpLeft = ui.position.left - position.left;
  97.  
  98.             console.log('coords x:'+tmpTop+' y:'+tmpLeft);
  99.             $('#cropcoordinates').val(tmpTop+'|'+tmpLeft);
  100.         }
  101.     }).resizable({
  102.         aspectRatio: true,
  103.         maxWidth: imgWidth,
  104.         maxHeight: imgHeight,
  105.         stop: function(event, ui) {
  106.             console.log('size:'+ui.size.width);
  107.             $('#cropsize').val(ui.size.width);
  108.         }
  109.     });
  110. }

La parte importante es la función setImage() la que calcula las coordenadas pero lo hace de forma erronea

El código PHP que recorta la imagen
Código PHP:
Ver original
  1. $image = Request::file('avatar');
  2.         $size = Request::get('cropsize');
  3.         list($fixLeft,$fixTop) = explode('|',Request::get('fix'));
  4.         list($posLeft,$posTop) = explode('|',Request::get('cropcoordinates'));
  5.  
  6.         if ($image->isValid()) {
  7.             $ext = $image->getClientOriginalExtension();
  8.             $fileName = md5(time().rand(1000,9999)).'.'.$ext;
  9.             $path = $_SERVER['DOCUMENT_ROOT'].'/img/avatars';
  10.             $image->move($path,$fileName);
  11.             $url = $path.'/'.$fileName;
  12.  
  13.             if ($fixTop > 0 || $fixLeft > 0) {
  14.                 if ($fixTop > 0)
  15.                     $posTop = $posTop + (($fixTop * $posTop) / 100);
  16.  
  17.                 if ($fixLeft > 0)
  18.                     $posLeft = $posLeft + (($fixLeft * $posLeft) / 100);
  19.  
  20.                 $size = $size + (($fixLeft * $size) / 100);
  21.             }
  22.            
  23.             $objImage = new Image();
  24.             $objImage->source($url);
  25.             $objImage->crop($posTop,$posLeft,$size,$size);
  26.             $objImage->save($url);

A ver si me pueden ayudar, cualquier información que requieran solo pregunten
__________________
Listo?, tendría que tener 60 puntos menos de IQ para considerarme listo!!!
-- Sheldon Cooper
http://twitter.com/nemutagk
PD: No contestaré temas vía mensaje personal =)