web-dev-qa-db-fra.com

Téléchargement de données d'image 'canvas' sur le serveur

Je dois télécharger les données d’image canvas sur le serveur (base de données) à la volée, c’est-à-dire créer un formulaire avec un fichier input = et poster les données d’image sans aucune interaction de l’utilisateur.

37
user192318

Vous n'avez pas besoin d'une entrée de fichier, il suffit d'obtenir les données avec ctx.getImageData() et de les poster sur le serveur avec Ajax. 

Voir Documentation MDN pour CanvasRenderingContext2D.getImageData() .

Mais vous ne pourrez pas obtenir les données d'image dans IE, même avec ExCanvas.

12
Fabien Ménager

FWIW, voici comment je le fais fonctionner.

Mon serveur est dans le moteur d'applications Google. J'envoie la sortie de canvas.toDataURL () dans le cadre d'une demande de publication à l'aide de jQuery.post. L'URL de données est une image codée en base64. Donc, sur le serveur, je le décode et le convertit en image

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

À partir du client, j'envoie les données comme ceci:

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

Ce n'est peut-être pas la meilleure façon de le faire, mais cela fonctionne.

35
Jayesh

Voici comment j'ai résolu ceci. Publier l'image sous forme de tableau base64 à l'aide de JavaScript, puis décoder et l'enregistrer sous forme d'image en utilisant PHP.

Côté client (JavaScript):

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

Côté serveur (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);
6
Firze

Voici une démo d'une application de signature en ligne que j'ai écrite l'année dernière Canvas Signature Demo . Cela présente l'avantage de publier uniquement les données vectorielles sur le serveur. Avec toutes les informations de chemin, vous pouvez également appliquer des algorithmes de lissage ou les redimensionner au besoin avant de les conserver.

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

Je stocke les données de chemin dans un champ caché et l'envoie au serveur. 

signature.js Logique principale ci-dessous:

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

Voici mon code .Net côté serveur (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();
}
3
B2K

Vous pouvez obtenir les données de l’image sous forme de données: url, cela ne fonctionne jusqu’à présent dans Firefox et Opera.

http://cow.neondragon.net/index.php/681-Canvas-Todataurl

0
Jeffrey Aylesworth