Copier automatiquement HTML5 canvas to contents

Disons que c'est ma toile, avec un visage malintentionné. Je veux utiliser toDataURL() pour exporter mon visage maléfique en tant que PNG; Cependant, toute la toile est rasterisée, y compris le «blanc» entre le visage maléfique et les bords de la toile.

 +---------------+ | | | | | (.Y. ) | | /_ | | \____/ | | | | | +---------------+ 

Quelle est la meilleure façon de recadrer / réduire / rétrécir ma toile à son contenu, donc mon PNG n'est pas plus grand que la «boîte de contournement» du visage, comme ci-dessous? La meilleure façon semble être la mise à l'échelle de la toile, mais en supposant que le contenu est dynamique …? Je suis sûr qu'il devrait y avoir une solution simple à cela, mais ça m'échappe, avec beaucoup de Googling.

 +------+ |(.Y. )| | /_ | |\____/| +------+ 

Merci!

 function cropImageFromCanvas(ctx, canvas) { var w = canvas.width, h = canvas.height, pix = {x:[], y:[]}, imageData = ctx.getImageData(0,0,canvas.width,canvas.height), x, y, index; for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { index = (y * w + x) * 4; if (imageData.data[index+3] > 0) { pix.x.push(x); pix.y.push(y); } } } pix.x.sort(function(a,b){return ab}); pix.y.sort(function(a,b){return ab}); var n = pix.x.length-1; w = pix.x[n] - pix.x[0]; h = pix.y[n] - pix.y[0]; var cut = ctx.getImageData(pix.x[0], pix.y[0], w, h); canvas.width = w; canvas.height = h; ctx.putImageData(cut, 0, 0); var image = canvas.toDataURL(); var win=window.open(image, '_blank'); win.focus(); } 

Si j'ai bien compris, vous voulez "couper" toute la proximité de votre image / dessin, et ajuster la toile à cette taille (comme si vous faites une commande "trim" dans Photoshop).

Voici comment je vais le faire.

  1. Exécutez tous les pixels de la toile vérifiant si leur composant alpha est> 0 (cela signifie que quelque chose est dessiné dans ce pixel). Alternativelly, vous pouvez vérifier les valeurs r, g, b, si votre fond de toile est rempli avec une couleur unie, par exemple.

  2. Obtenez les coordonnées du pixel le plus à gauche non vide, et identique pour le bas le plus à droite. Vous obtiendrez donc les coordonnées d'un «rectangle» imaginaire contenant la zone de la toile qui n'est pas vide.

  3. Rangez cette région de pixeldata.

  4. Redimensionnez votre toile à ses nouvelles dimensions (celles de la région que nous avons obtenues à l'étape 2.)

  5. Collez la région enregistrée dans le canevas.

Et voilà 🙂

Le pixeldata d'accès est assez lent en fonction de la taille de votre toile (si c'est énorme, cela peut prendre un certain temps). Il y a quelques optimisations pour travailler avec pixeldata de toile brute (je pense qu'il y a un article sur ce sujet à MDN), je vous suggère de google à propos de ça.

J'ai préparé un petit croquis dans jsFiddle que vous pouvez utiliser comme point de départ pour votre code.

Exemple de travail à jsFiddle

J'espère que je t'ai aidé.
C :.