2009-10-19 8 views
36

Ich muss die Canvas-Bilddaten auf den Server (Datenbank) im laufenden Betrieb hochladen, dh ich muss ein Formular erstellen und mit einer Eingabe = Datei, und die Bilddaten hochladen ohne irgendeine Benutzerinteraktion.Upload 'Canvas' Bilddaten auf den Server

Antwort

11

Sie müssen keine Datei eingegeben wird, erhalten nur die Daten mit ctx.getImageData() und per Post an den Server mit Ajax.

Siehe MDN Documentation for CanvasRenderingContext2D.getImageData().

Aber Sie werden nicht in der Lage, die Bilddaten in IE zu erhalten, auch mit ExCanvas.

+0

Hat jemand bekam dies tatsächlich zu arbeiten ? Ich habe bekommen, dass Daten von getImageData() zurückgegeben werden kann an den Server, aber ich kann nicht herausfinden, wie. Ich habe versucht, verschiedene Optionen in jQuery.ajax und jQuery.post, aber ich konnte nicht herausfinden, wie Sie Bilddaten in Ajax-Anfrage angeben. Mein Server kann die von mir gesendeten Daten nicht interpretieren. Ich konnte auch keine Code-Beispiele finden. Hast du irgendwelche Hinweise? (Ich habe sichergestellt, dass der Server korrekt funktioniert, indem ich die gleiche Anfrage mit Curl als Client mache.) Danke. – Jayesh

+1

ok, habe es funktioniert. Code in die Antwort eingefügt. – Jayesh

+3

Es ist möglich, es auf IE mit dem fxCanvas (nicht mit ExCanvas) zu verwenden. Sie müssen die Funktion toDataURL ("image/png", Funktion (fxUrl) {...}) verwenden. –

34

FWIW, so habe ich es funktioniert.

Mein Server ist in Google App Engine. Ich sende canvas.toDataURL() die Ausgabe als Teil der Post-Anfrage mit jQuery.post. Die Daten-URL sind base64-codierte Bilddaten. Also auf dem Server entschlüsseln ich es und wandelt es in Bild

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() 

Von Client ich die Daten wie folgt an:

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

Dies ist nicht der beste Weg sein kann, es zu tun, aber es funktioniert.

+0

Danke funktioniert wie Butter .. :) – Surya

+0

die img Argument wird geschnitten werden, wenn es zu groß ist, haben Hast du das jemals getroffen? – ernest

+0

@ernest Ich habe nach den Posteinschränkungen gesucht, die du erwähnt hast (ich wusste über die Beschränkung der Anfrage) und ich finde nicht, dass http://www.w3schools.com/tags/ref_httpmethods.asp W3school sagt: "POST-Anfragen haben keine Einschränkungen bei der Datenlänge " – ccsakuweb

2

Hier ist eine Demo einer Online-Signatur-App, die ich letztes Jahr schrieb Canvas Signature Demo. Dies hat den Vorteil, dass nur die Vektordaten an den Server gesendet werden. Mit allen Pfadinformationen können Sie auch Glättungsalgorithmen anwenden oder nach Bedarf skalieren, bevor Sie fortfahren.

<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> 

Ich speichere die Pfaddaten in ein verstecktes Feld und posten das auf dem Server.

signature.js Core-Logik unter:

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(); 
    } 
} 

Hier ist mein relevanter Server-Seite .NET-Code (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

Hier ist, wie ich das gelöst habe. Veröffentlichen Sie das Bild als Base64-Array mit JavaScript und dekodieren und speichern Sie es als Bild mit PHP.

Client-Seite (JavaScript):

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

Server-Seite (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); 
Verwandte Themen