J'essaie de créer une image miniature du côté client en utilisant javascript et un élément canvas, mais quand je rétrécis l'image, ça a l'air terrible. Il semble qu'il ait été réduit dans Photoshop avec le rééchantillonnage défini sur `` Voisin le plus proche '' au lieu de Bicubic. Je sais qu'il est possible de faire en sorte que cela soit correct, car ce site peut très bien le faire en utilisant également une toile. J'ai essayé d'utiliser le même code que celui indiqué dans le lien "[Source]", mais il a toujours l'air terrible. Y a-t-il quelque chose qui me manque, un paramètre qui doit être défini ou quelque chose?
ÉDITER:
J'essaie de redimensionner un jpg. J'ai essayé de redimensionner le même jpg sur le site lié et dans photoshop, et il a l'air bien lorsqu'il est réduit.
Voici le code pertinent:
reader.onloadend = function(e)
{
var img = new Image();
var ctx = canvas.getContext("2d");
var canvasCopy = document.createElement("canvas");
var copyContext = canvasCopy.getContext("2d");
img.onload = function()
{
var ratio = 1;
if(img.width > maxWidth)
ratio = maxWidth / img.width;
else if(img.height > maxHeight)
ratio = maxHeight / img.height;
canvasCopy.width = img.width;
canvasCopy.height = img.height;
copyContext.drawImage(img, 0, 0);
canvas.width = img.width * ratio;
canvas.height = img.height * ratio;
ctx.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvas.width, canvas.height);
};
img.src = reader.result;
}
EDIT2:
On dirait que je me suis trompé, le site Web lié ne faisait pas mieux de réduire la taille de l'image. J'ai essayé les autres méthodes suggérées et aucune d'entre elles n'est meilleure. C'est ce que les différentes méthodes ont abouti:
Photoshop:
Toile:
Image avec rendu d'image: optimisationQualité définie et mise à l'échelle avec largeur / hauteur:
Image avec rendu d'image: optimisationQualité définie et mise à l'échelle avec -moz-transform:
Redimensionnement de la toile sur pixastic:
Je suppose que cela signifie que Firefox n'utilise pas l'échantillonnage bicubique comme il est censé le faire. Je vais devoir attendre jusqu'à ce qu'ils l'ajoutent réellement.
EDIT3:
la source
Réponses:
Alors, que faites-vous si tous les navigateurs (en fait, Chrome 5 m'en ont donné un assez bon) ne vous offrent pas une qualité de rééchantillonnage suffisante? Vous les mettez alors en œuvre vous-même! Oh allez, nous entrons dans la nouvelle ère du Web 3.0, des navigateurs compatibles HTML5, des compilateurs javascript JIT super optimisés, des machines multicœurs (†), avec des tonnes de mémoire, de quoi avez-vous peur? Hé, il y a le mot java en javascript, donc ça devrait garantir les performances, non? Voici, le code de génération de vignettes:
... avec lequel vous pouvez produire des résultats comme ceux-ci!
de toute façon, voici une version «fixe» de votre exemple:
Il est maintenant temps de comparer vos meilleurs navigateurs et de voir lequel augmentera le moins la tension artérielle de votre client!
Umm, où est ma balise sarcasme?
(puisque de nombreuses parties du code sont basées sur Anrieff Gallery Generator, est-il également couvert par la GPL2? Je ne sais pas)
† en raison de la limitation de javascript, le multicœur n'est pas pris en charge.
la source
Algorithme de redimensionnement / rééchantillonnage d'image rapide utilisant un filtre Hermite avec JavaScript. Soutenir la transparence, donne une bonne qualité. Aperçu:
Mise à jour : version 2.0 ajoutée sur GitHub (plus rapide, web travailleurs + objets transférables). Enfin, je l'ai fait fonctionner!
Git: https://github.com/viliusle/Hermite-resize
Démo: http://viliusle.github.io/miniPaint/
la source
Essayez pica - c'est un resizer hautement optimisé avec des algorithmes sélectionnables. Voir la démo .
Par exemple, l'image originale du premier message est redimensionnée en 120 ms avec le filtre Lanczos et la fenêtre 3px ou 60ms avec le filtre Box et la fenêtre 0,5px. Pour une énorme image de 17 Mo, le redimensionnement de 5000 x 3000 pixels prend environ 1 seconde sur le bureau et 3 secondes sur le mobile.
Tous les principes de redimensionnement ont été très bien décrits dans ce fil, et pica n'ajoute pas la science des fusées. Mais il est très bien optimisé pour les JIT modernes et est prêt à être utilisé hors de la boîte (via npm ou bower). En outre, il utilise des webworkers lorsqu'ils sont disponibles pour éviter les gels d'interface.
Je prévois également d'ajouter bientôt un support de masque flou, car il est très utile après la réduction d'échelle.
la source
Je sais que c'est un vieux fil de discussion, mais il pourrait être utile pour certaines personnes comme moi que des mois plus tard, ce problème se pose pour la première fois.
Voici un code qui redimensionne l'image chaque fois que vous rechargez l'image. Je suis conscient que ce n'est pas optimal du tout, mais je le fournis comme preuve de concept.
Aussi, désolé d'utiliser jQuery pour des sélecteurs simples mais je me sens trop à l'aise avec la syntaxe.
Ma fonction createImage est appelée une fois lorsque le document est chargé et ensuite elle est appelée à chaque fois que la fenêtre reçoit un événement de redimensionnement.
Je l'ai testé dans Chrome 6 et Firefox 3.6, tous deux sur Mac. Cette "technique" mange le processeur comme s'il s'agissait de crème glacée en été, mais elle fait l'affaire.
la source
J'ai mis en place quelques algorithmes pour effectuer une interpolation d'image sur des tableaux de pixels de toile html qui pourraient être utiles ici:
https://web.archive.org/web/20170104190425/http://jsperf.com:80/pixel-interpolation/2
Ceux-ci peuvent être copiés / collés et peuvent être utilisés à l'intérieur des travailleurs Web pour redimensionner les images (ou toute autre opération qui nécessite une interpolation - je les utilise pour défier les images en ce moment).
Je n'ai pas ajouté les lanczos ci-dessus, alors n'hésitez pas à ajouter cela à titre de comparaison si vous le souhaitez.
la source
Il s'agit d'une fonction javascript adaptée du code @ Telanor. Lors du passage d'une image base64 comme premier argument à la fonction, elle renvoie la base64 de l'image redimensionnée. maxWidth et maxHeight sont facultatifs.
la source
Je vous suggère fortement de vérifier ce lien et de vous assurer qu'il est défini sur true.
la source
Si vous essayez simplement de redimensionner une image, je recommanderais de définir
width
etheight
de l'image avec CSS. Voici un petit exemple:Notez que le
height
etwidth
peut également être défini à l'aide de JavaScript. Voici un exemple de code rapide:De plus, pour vous assurer que l'image redimensionnée semble bonne, ajoutez les règles css suivantes au sélecteur d'image:
-ms-interpolation-mode: bicubic
: introduire dans IE7image-rendering: optimizeQuality
: introduit dans FireFox 3.6Pour autant que je sache, tous les navigateurs sauf IE utilisent un algorithme bicubique pour redimensionner les images par défaut, de sorte que vos images redimensionnées devraient bien paraître dans Firefox et Chrome.
Si le réglage du CSS
width
etheight
ne fonctionne pas, vous voudrez peut-être jouer avec un CSStransform
:-moz-transform: scale(sx[, sy])
-webkit-transform:scale(sx[, sy])
Si pour une raison quelconque vous avez besoin d'utiliser un canevas, veuillez noter qu'il existe deux façons de redimensionner une image: en redimensionnant le canevas avec css ou en dessinant l'image à une taille plus petite.
Voir cette question pour plus de détails.
la source
Pour redimensionner l'image avec une largeur inférieure à l'original, j'utilise:
et ça marche =).
la source
j'ai obtenu cette image en cliquant avec le bouton droit sur l'élément canvas dans firefox et en l'enregistrant sous.
de toute façon, voici une version «fixe» de votre exemple:
la source
Le problème avec certaines de ces solutions est qu'elles accèdent directement aux données de pixels et les parcourent pour effectuer le sous-échantillonnage. Selon la taille de l'image, cela peut être très gourmand en ressources, et il serait préférable d'utiliser les algorithmes internes du navigateur.
La fonction drawImage () utilise une méthode de rééchantillonnage par interpolation linéaire, le plus proche voisin. Cela fonctionne bien lorsque vous ne redimensionnez pas plus de la moitié de la taille d'origine .
Si vous bouclez pour ne redimensionner que la moitié au maximum à la fois, les résultats seraient assez bons et beaucoup plus rapides que l'accès aux données de pixels.
Cette fonction sous-échantillonne la moitié à la fois jusqu'à atteindre la taille souhaitée:
Crédits à ce post
la source
Donc, quelque chose d'intéressant que j'ai trouvé il y a quelque temps en travaillant avec un canevas qui pourrait être utile:
Pour redimensionner le contrôle de canevas seul, vous devez utiliser les attributs
height=""
etwidth=""
(oucanvas.width
/ lescanvas.height
éléments). Si vous utilisez CSS pour redimensionner le canevas, il étirera (c.-à-d.: Redimensionner) le contenu du canevas pour l'adapter au canevas complet (plutôt que d'augmenter ou de diminuer simplement la zone du canevas).Il vaudrait la peine d'essayer de dessiner l'image dans un contrôle de canevas avec les attributs de hauteur et de largeur définis à la taille de l'image, puis d'utiliser CSS pour redimensionner le canevas à la taille que vous recherchez. Peut-être que cela utiliserait un algorithme de redimensionnement différent.
Il convient également de noter que le canevas a des effets différents dans différents navigateurs (et même dans différentes versions de différents navigateurs). Les algorithmes et techniques utilisés dans les navigateurs sont susceptibles de changer avec le temps (en particulier avec Firefox 4 et Chrome 6 qui sortiront si tôt, ce qui mettra fortement l'accent sur les performances de rendu de la toile).
En outre, vous pouvez également essayer SVG, car il utilise probablement un algorithme différent également.
Bonne chance!
la source
J'ai l'impression que le module que j'ai écrit produira des résultats similaires à Photoshop, car il préserve les données de couleur en les moyennant, sans appliquer d'algorithme. C'est un peu lent, mais pour moi, c'est le meilleur, car il préserve toutes les données de couleur.
https://github.com/danschumann/limby-resize/blob/master/lib/canvas_resize.js
Il ne prend pas le voisin le plus proche et ne supprime pas d'autres pixels, ou échantillonne un groupe et prend une moyenne aléatoire. Il prend la proportion exacte que chaque pixel source doit produire dans le pixel de destination. La couleur moyenne des pixels dans la source sera la couleur moyenne des pixels dans la destination, ce que ces autres formules, je pense, ne seront pas.
un exemple d'utilisation est au bas de https://github.com/danschumann/limby-resize
MISE À JOUR OCT 2018 : De nos jours, mon exemple est plus académique qu'autre chose. Webgl est à peu près à 100%, il vaut donc mieux redimensionner avec cela pour produire des résultats similaires, mais plus rapidement. PICA.js fait cela, je crois. -
la source
J'ai converti la réponse de @ syockit ainsi que l'approche descendante en un service Angular réutilisable pour tous ceux qui sont intéressés: https://gist.github.com/fisch0920/37bac5e741eaec60e983
J'ai inclus les deux solutions car elles ont chacune leurs avantages / inconvénients. L'approche de convolution lanczos est de meilleure qualité au prix d'être plus lente, tandis que l'approche de réduction d'échelle par étapes produit des résultats raisonnablement anti-crénelés et est beaucoup plus rapide.
Exemple d'utilisation:
la source
Resizer d'image Javascript simple et rapide:
https://github.com/calvintwr/blitz-hermite-resize
L'histoire
C'est vraiment après de nombreuses séries de recherches, de lecture et d'essais.
L'algorithme de redimensionnement utilise le script Hermite de @ ViliusL (le redimensionneur Hermite est vraiment le plus rapide et donne une sortie raisonnablement bonne). Etendu avec les fonctionnalités dont vous avez besoin.
Forks 1 travailleur pour effectuer le redimensionnement afin qu'il ne gèle pas votre navigateur lors du redimensionnement, contrairement à tous les autres redimensionneurs JS.
la source
Merci @syockit pour une réponse géniale. cependant, j'ai dû reformater un peu comme suit pour le faire fonctionner. Peut-être en raison de problèmes de numérisation DOM:
la source
Je viens de lancer une page de comparaisons côte à côte et à moins que quelque chose n'ait changé récemment, je ne pouvais pas voir de meilleure réduction des effectifs (mise à l'échelle) en utilisant canvas vs css simple. J'ai testé dans FF6 Mac OSX 10.7. Toujours légèrement doux par rapport à l'original.
Cependant, je suis tombé sur quelque chose qui a fait une énorme différence et qui était d'utiliser des filtres d'image dans les navigateurs qui prennent en charge le canevas. Vous pouvez réellement manipuler des images comme vous pouvez le faire dans Photoshop avec flou, netteté, saturation, ondulation, niveaux de gris, etc.
J'ai ensuite trouvé un plug-in jQuery génial qui rend l'application de ces filtres un jeu d'enfant: http://codecanyon.net/item/jsmanipulate-jquery-image-manipulation-plugin/428234
J'applique simplement le filtre de netteté juste après avoir redimensionné l'image, ce qui devrait vous donner l'effet souhaité. Je n'ai même pas eu à utiliser d'élément canvas.
la source
Vous cherchez une autre excellente solution simple?
Cette solution utilisera l'algorithme de redimensionnement du navigateur! :)
la source