2009-10-19 12 views

Respuesta

11

No es necesario un archivo de entrada, acaba de obtener los datos con ctx.getImageData() y que lo ponga al servidor con el Ajax.

Ver el MDN Documentation for CanvasRenderingContext2D.getImageData().

Pero no podrá obtener los datos de imagen en IE, incluso con ExCanvas.

+0

¿Alguien consiguió que esto funcione realmente ? Obtuve que los datos devueltos de getImageData() pueden ser POST enviados al servidor, pero no puedo entender cómo. Intenté usar diferentes opciones en jQuery.ajax y jQuery.post, pero no pude encontrar la forma de especificar los datos de imagen en la solicitud ajax. Mi servidor no puede interpretar los datos que envío. No pude encontrar ningún ejemplo de código tampoco. ¿Tienes algún puntero? (Me aseguré de que el servidor funcionara correctamente haciendo la misma solicitud con Curl como cliente.) Gracias. – Jayesh

+1

bien, lo tengo funcionando. código pegado en la respuesta. – Jayesh

+3

Es posible usarlo en IE con fxCanvas (no con ExCanvas). Necesita usar la función toDataURL ("image/png", function (fxUrl) {...}). –

34

FWIW, así es como lo conseguí trabajando.

Mi servidor está en el motor de la aplicación de google. Envío el resultado de canvas.toDataURL() como parte de una solicitud posterior usando jQuery.post. La URL de datos es datos de imagen codificados en base64. Así en el servidor que descodificarlo y convertirlo en la imagen

import re 
import base64 
class TnUploadHandler(webapp.RequestHandler): 
    dataUrlPattern = re.compile('data:image/(png|jpeg);base64,(.*)$') 
    def post(self): 
     uid = self.request.get('uid') 
     img = self.request.get('img') 

     imgb64 = self.dataUrlPattern.match(img).group(2) 
     if imgb64 is not None and len(imgb64) > 0: 
      thumbnail = Thumbnail(
        uid = uid, img = db.Blob(base64.b64decode(imgb64))) 
      thumbnail.put() 

Desde el cliente que envío los datos de la siguiente manera:

$.post('/upload', 
     { 
      uid : uid, 
      img : canvas.toDataURL('image/jpeg') 
     }, 
     function(data) {}); 

esto puede no ser la mejor manera de hacerlo, pero funciona.

+0

Gracias funciona como la mantequilla :) :) – Surya

+0

el argumento img se cortará si es demasiado grande, tiene ¿Alguna vez te has encontrado con eso? – ernest

+0

@ernest Tengo la búsqueda de las restricciones de publicación que mencionaste (sabía acerca de la limitación de solicitud de obtención) y no encuentro que http://www.w3schools.com/tags/ref_httpmethods.asp W3school diga "Las solicitudes POST no tienen restricciones en la longitud de datos " – ccsakuweb

2

Aquí hay una demostración de una aplicación de firma en línea que escribí el año pasado Canvas Signature Demo. Esto tiene la ventaja de publicar solo los datos vectoriales en el servidor. Con toda la información de ruta, también puede aplicar algoritmos de suavizado o escalarla según sea necesario antes de continuar.

<canvas id="signature" width="300" height="100"></canvas> 
<form method="post" id="signature_form" action="signing.aspx"> 
<input type="hidden" name="paths" id="paths"/> 
    <p><label>Cover #</label> <input type="text" id="covernumber" name="covernumber"/> 
    <input type="submit" id="save" value="Save"/> 
</form> 

Guardo los datos de la ruta en un campo oculto y los publico en el servidor.

signature.js lógica de la base de abajo:

mouseDown: function(event) { 
    var point = this.getRelativePoint(event); 
    this.paths.push([ point ]); 
    this.ctx.fillRect(point.x,point.y,1,1); 
    this.penDown = true; 
    this.updateField(); 
}, 
mouseUp: function(event) { 
    this.penDown = false; 
    this.ctx.closePath(); 
    if (Prototype.Browser.IE && event.srcElement.tagName != "INPUT") { 
     var ver = getInternetExplorerVersion(); 
     if (ver >= 8 && ver < 9 && document.selection) { 
      document.selection.empty(); 
     } 
    } 
}, 
mouseMove: function(event) { 
    if (this.penDown) { 
     var lastPath = this.paths[ this.paths.length - 1 ]; 
     var lastPoint = lastPath[ lastPath.length - 1 ]; 
     var point = this.getRelativePoint(event); 
     lastPath.push(point); 
     this.ctx.strokeStyle = "#000000"; 
     this.ctx.beginPath(); 
     this.ctx.moveTo(lastPoint.x,lastPoint.y); 
     this.ctx.lineTo(point.x, point.y); 
     this.ctx.stroke(); 
     this.ctx.closePath(); 
     this.updateField(); 
    } 
}, 
updateField: function() { 
    if (this.field) { 
     this.field.value = this.paths.toJSON(); 
    } 
} 

Aquí está mi código .Net lado del servidor correspondiente (C#).

if (Request("paths")) { 
    var objBitmap : Bitmap = new Bitmap(300, 100); 
    var objGraphics : Graphics = Graphics.FromImage(objBitmap); 
    objGraphics.Clear(Color.Transparent); 
    objGraphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; 

    var paths:Array = eval(Request("paths")) || []; 
    var p : int; 
    var q : int; 
    var path : Array; 

    for (p = 0; p< paths.length; p++) { 
     var path = paths[p]; 
     if (path.length == 1) { 
      objGraphics.DrawRectangle(new Pen(Color.Black), path[0].x, path[0].y, 1, 1); 
     } else { 
      for (q = 1; q<path.length; q++) { 
       var prev = path[q-1]; 
       var curr = path[q]; 
       objGraphics.DrawLine(new Pen(Color.Black), parseInt(prev.x),parseInt(prev.y),parseInt(curr.x),parseInt(curr.y)); 
      } 
     } 
    } 
    objBitmap.Save("C:\\temp\\" + Request("covernumber") + ".png", ImageFormat.Png); 
    objBitmap.Dispose(); 
    objGraphics.Dispose(); 
} 
5

Así es como he resuelto esto. Publicando la imagen como una matriz base64 usando JavaScript y luego decodificándola y guardándola como una imagen usando PHP.

lado del cliente (JavaScript):

$.post('/ajax/uploadthumbnail', 
    { 
     id : id, 
     img : canvas.toDataURL("image/png") 
    }, function(data) { 
     console.log(data); 
    }); 

lado del servidor (PHP):

$img = $_POST['img']; 
$img = str_replace('data:image/png;base64,', '', $img); 
$img = str_replace(' ', '+', $img); 
$data = base64_decode($img); 
$file = $_SERVER['DOCUMENT_ROOT'] . '/images/some_name.png'; 
file_put_contents($file, $data); 
Cuestiones relacionadas