Ho bisogno di caricare i dati dell'immagine canvas sul server (database) al volo, cioè, ho bisogno di creare un modulo e con un input = file, e postare i dati dell'immagine senza alcuna interazione dell'utente.Caricamento dati immagine 'canvas' sul server
risposta
Non hai bisogno di un ingresso di file, basta avere i dati con ctx.getImageData()
e post al server con l'Ajax.
Vedere MDN Documentation for CanvasRenderingContext2D.getImageData()
.
Ma non è possibile ottenere i dati di immagine in IE, anche con ExCanvas
.
È possibile ottenere i dati di immagine sotto forma di dati: url, questo funziona solo in Firefox e Opera finora però.
... e Safari (e ogni altro browser basato su webkit) – olliej
FWIW, è così che ho funzionato.
Il mio server è in google app engine. Invio l'output canvas.toDataURL() come parte della richiesta post utilizzando jQuery.post. L'URL dei dati è costituito da dati immagine codificati in base 64. Così sul server di decodifico e convertirlo in immagine
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()
Da cliente mando i dati in questo modo:
$.post('/upload',
{
uid : uid,
img : canvas.toDataURL('image/jpeg')
},
function(data) {});
questo potrebbe non essere il modo migliore per farlo, ma funziona.
Grazie funziona come burro .. :) – Surya
l'argomento img verrà tagliato se è troppo grande, avere l'hai mai incontrato? – ernest
@ernest Ho cercato le restrizioni post che hai menzionato (sapevo di ottenere la limitazione delle richieste) e non trovo che http://www.w3schools.com/tags/ref_httpmethods.asp W3school dice "Le richieste POST non hanno restrizioni sulla lunghezza dei dati " – ccsakuweb
Ecco una demo di un'app di firma online che ho scritto l'anno scorso Canvas Signature Demo. Questo ha il vantaggio di inviare solo i dati vettoriali al server. Con tutte le informazioni sul percorso, è possibile anche applicare gli algoritmi di livellamento o ridimensionarlo in base alle esigenze prima di continuare.
<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>
Memorizzo i dati del percorso in un campo nascosto e lo invio al server.
signature.js logica di nucleo di seguito:
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();
}
}
Ecco il mio codice lato server Net rilevanti (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();
}
Ecco come ho risolto questo. Pubblicare l'immagine come array base64 usando JavaScript e decodificandolo e salvandolo come immagine usando PHP.
lato client (JavaScript):
$.post('/ajax/uploadthumbnail',
{
id : id,
img : canvas.toDataURL("image/png")
}, function(data) {
console.log(data);
});
lato server (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);
Qualcuno ha questo al lavoro in realtà ? Ho ottenuto che i dati restituiti da getImageData() possono essere inviati al server, ma non riesco a capire come. Ho provato a utilizzare diverse opzioni in jQuery.ajax e jQuery.post, ma non sono riuscito a capire come specificare i dati dell'immagine in una richiesta Ajax. Il mio server non può interpretare i dati che invio. Non sono riuscito a trovare alcun esempio di codice. Hai qualche indicazione? (Ho verificato che il server funzioni correttamente eseguendo la stessa richiesta con Curl come client.) Grazie. – Jayesh
ok, ho funzionato. codice incollato nella risposta. – Jayesh
È possibile utilizzarlo su IE con fxCanvas (non con ExCanvas). È necessario utilizzare la funzione toDataURL ("image/png", function (fxUrl) {...}). –