Ich versuche, auf der Clientseite ein Miniaturbild mit Javascript und einem Canvas-Element zu erstellen, aber wenn ich das Bild verkleinere, sieht es schrecklich aus. Es sieht so aus, als wäre es in Photoshop verkleinert worden, wobei das Resampling auf "Nearest Neighbor" anstelle von Bicubic eingestellt war. Ich weiß, dass es möglich ist, dass dies richtig aussieht, da diese Seite es auch mit einer Leinwand gut machen kann. Ich habe versucht, denselben Code wie im Link "[Quelle]" zu verwenden, aber es sieht immer noch schrecklich aus. Fehlt mir etwas, eine Einstellung, die eingestellt werden muss, oder so?
BEARBEITEN:
Ich versuche, die Größe eines JPGs zu ändern. Ich habe versucht, die Größe desselben JPGs auf der verlinkten Site und in Photoshop zu ändern, und es sieht gut aus, wenn es verkleinert wird.
Hier ist der relevante Code:
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:
Ich habe mich wohl geirrt, die verlinkte Website hat es nicht besser gemacht, das Bild zu verkleinern. Ich habe die anderen vorgeschlagenen Methoden ausprobiert und keine davon sieht besser aus. Dies führte zu den verschiedenen Methoden:
Photoshop:
Segeltuch:
Bild mit Bildwiedergabe: OptimizeQuality festgelegt und skaliert mit Breite / Höhe:
Bild mit Bildwiedergabe: OptimizeQuality festgelegt und skaliert mit -moz-transform:
Leinwandgröße auf Pixastic ändern:
Ich denke, dies bedeutet, dass Firefox keine bikubischen Proben verwendet, wie es soll. Ich muss nur warten, bis sie es tatsächlich hinzufügen.
EDIT3:
quelle
Antworten:
Was tun Sie also, wenn alle Browser (Chrome 5 hat mir einen recht guten gegeben) Ihnen keine ausreichend gute Resampling-Qualität bieten? Sie implementieren sie dann selbst! Ach komm schon, wir betreten das neue Zeitalter von Web 3.0, HTML5-kompatiblen Browsern, superoptimierten JIT-Javascript-Compilern, Multi-Core-Computern (†) und viel Speicher. Wovor haben Sie Angst? Hey, es gibt das Wort Java in Javascript, das sollte also die Leistung garantieren, oder? Siehe, das Miniaturbild generiert Code:
... mit denen Sie solche Ergebnisse erzielen können!
Hier ist eine 'feste' Version Ihres Beispiels:
Jetzt ist es Zeit, Ihre besten Browser da draußen zu platzieren und herauszufinden, welcher den Blutdruck Ihres Kunden am wenigsten erhöht!
Ähm, wo ist mein Sarkasmus-Tag?
(Da viele Teile des Codes auf dem Anrieff Gallery Generator basieren, wird er auch unter GPL2 behandelt? Ich weiß nicht)
† Aufgrund der Einschränkung von Javascript wird Multi-Core nicht unterstützt.
quelle
Schneller Algorithmus zur Größenänderung / Neuabtastung von Bildern mithilfe des Hermite- Filters mit JavaScript. Unterstützung Transparenz, gibt gute Qualität. Vorschau:
Update : Version 2.0 auf GitHub hinzugefügt (schneller, Web Worker + übertragbare Objekte). Endlich habe ich es geschafft!
Git: https://github.com/viliusle/Hermite-resize
Demo: http://viliusle.github.io/miniPaint/
quelle
Probieren Sie pica aus - das ist ein hochoptimierter Resizer mit wählbaren Algorithmen. Siehe Demo .
Beispielsweise wird die Größe des Originalbilds aus dem ersten Beitrag in 120 ms mit Lanczos-Filter und 3px-Fenster oder in 60 ms mit Box-Filter und 0,5px-Fenster geändert. Für ein riesiges 17-MB-Bild dauert die Größenänderung von 5000 x 3000 Pixel ca. 1 Sekunde auf dem Desktop und 3 Sekunden auf dem Handy.
Alle Größenänderungsprinzipien wurden in diesem Thread sehr gut beschrieben, und Pica fügt keine Raketenwissenschaft hinzu. Aber es ist sehr gut für moderne JITs optimiert und sofort einsatzbereit (über npm oder bower). Außerdem werden Webworker verwendet, sofern verfügbar, um ein Einfrieren der Benutzeroberfläche zu vermeiden.
Ich habe auch vor, bald Unterstützung für unscharfe Masken hinzuzufügen, da dies nach dem Verkleinern sehr nützlich ist.
quelle
Ich weiß, dass dies ein alter Thread ist, aber es könnte für einige Leute wie mich nützlich sein, die Monate später zum ersten Mal auf dieses Problem stoßen.
Hier ist ein Code, der die Größe des Bildes jedes Mal ändert, wenn Sie das Bild neu laden. Ich bin mir bewusst, dass dies überhaupt nicht optimal ist, aber ich biete es als Proof of Concept an.
Es tut mir auch leid, dass ich jQuery für einfache Selektoren verwendet habe, aber ich fühle mich mit der Syntax einfach zu wohl.
Meine Funktion createImage wird beim Laden des Dokuments einmal aufgerufen und danach jedes Mal aufgerufen, wenn das Fenster ein Größenänderungsereignis empfängt.
Ich habe es in Chrome 6 und Firefox 3.6 getestet, beide auf dem Mac. Diese "Technik" frisst Prozessor, als wäre es im Sommer Eis, aber es macht den Trick.
quelle
Ich habe einige Algorithmen für die Bildinterpolation auf HTML-Canvas-Pixel-Arrays entwickelt, die hier nützlich sein könnten:
https://web.archive.org/web/20170104190425/http://jsperf.com:80/pixel-interpolation/2
Diese können kopiert / eingefügt und innerhalb von Web-Workern verwendet werden, um die Größe von Bildern zu ändern (oder jede andere Operation, die eine Interpolation erfordert - ich verwende sie derzeit, um Bilder zu entschärfen).
Ich habe das lanczos-Zeug oben nicht hinzugefügt, also zögern Sie nicht, es als Vergleich hinzuzufügen, wenn Sie möchten.
quelle
Dies ist eine Javascript-Funktion, die aus dem Code von @ Telanor angepasst wurde. Wenn Sie ein Image base64 als erstes Argument an die Funktion übergeben, wird das base64 des verkleinerten Images zurückgegeben. maxWidth und maxHeight sind optional.
quelle
Ich würde Ihnen dringend empfehlen, diesen Link zu überprüfen und sicherzustellen, dass er auf true gesetzt ist.
quelle
Wenn Sie einfach nur du versuchen , ein Bild , um die Größe, würde ich Einstellung empfehlen
width
undheight
des Bildes mit CSS. Hier ist ein kurzes Beispiel:Beachten Sie, dass das
height
undwidth
auch mit JavaScript eingestellt werden kann. Hier ist ein kurzes Codebeispiel:Fügen Sie der Bildauswahl außerdem die folgenden CSS-Regeln hinzu, um sicherzustellen, dass das Bild mit geänderter Größe gut aussieht:
-ms-interpolation-mode: bicubic
: in IE7 einführenimage-rendering: optimizeQuality
: eingeführt in FireFox 3.6Soweit ich das beurteilen kann, verwenden alle Browser außer dem IE standardmäßig einen bikubischen Algorithmus, um die Größe von Bildern zu ändern, sodass die Größe Ihrer Bilder in Firefox und Chrome gut aussehen sollte.
Wenn das CSS eingestellt ist
width
undheight
nicht funktioniert, möchten Sie möglicherweise mit einem CSS spielentransform
:-moz-transform: scale(sx[, sy])
-webkit-transform:scale(sx[, sy])
Wenn aus irgendeinem Grund Sie brauchen eine Leinwand zu verwenden, beachten Sie bitte , dass es zwei Möglichkeiten gibt ein Bild Resize sein: durch die Leinwand mit CSS Ändern der Größe oder durch die Bildzeichnungs bei einer kleineren Größe.
Weitere Informationen finden Sie in dieser Frage .
quelle
Für die Größenänderung auf ein Bild mit einer Breite, die kleiner als das Original ist, verwende ich:
und es funktioniert =).
quelle
Ich habe dieses Bild erhalten, indem ich mit der rechten Maustaste auf das Canvas-Element in Firefox geklickt und unter gespeichert habe.
Hier ist eine 'feste' Version Ihres Beispiels:
quelle
Das Problem bei einigen dieser Lösungen besteht darin, dass sie direkt auf die Pixeldaten zugreifen und diese durchlaufen, um das Downsampling durchzuführen. Abhängig von der Größe des Bildes kann dies sehr ressourcenintensiv sein, und es ist besser, die internen Algorithmen des Browsers zu verwenden.
Die Funktion drawImage () verwendet eine Resampling-Methode mit linearer Interpolation und nächstem Nachbarn. Das funktioniert gut, wenn Sie nicht mehr als die Hälfte der Originalgröße verkleinern .
Wenn Sie eine Schleife ausführen, um jeweils nur die Hälfte der Größe zu ändern, sind die Ergebnisse recht gut und viel schneller als der Zugriff auf Pixeldaten.
Diese Funktion wird jeweils auf die Hälfte heruntergesampelt, bis die gewünschte Größe erreicht ist:
Credits zu diesem Beitrag
quelle
Also etwas Interessantes, das ich vor einiger Zeit bei der Arbeit mit Leinwand gefunden habe und das hilfreich sein könnte:
Um die Größe des Canvas-Steuerelements selbst zu ändern, müssen Sie die Attribute
height=""
undwidth=""
(odercanvas.width
/) verwendencanvas.height
elements) verwenden. Wenn Sie CSS verwenden, um die Größe der Leinwand zu ändern, wird der Inhalt der Leinwand tatsächlich so gedehnt (dh verkleinert), dass er zur gesamten Leinwand passt (anstatt einfach den Bereich der Leinwand zu vergrößern oder zu verkleinern).Es lohnt sich, das Bild in ein Canvas-Steuerelement zu zeichnen, dessen Höhen- und Breitenattribute auf die Größe des Bildes eingestellt sind, und dann die Größe der Leinwand mithilfe von CSS auf die gewünschte Größe zu ändern. Möglicherweise würde dies einen anderen Größenänderungsalgorithmus verwenden.
Es sollte auch beachtet werden, dass Canvas in verschiedenen Browsern (und sogar in verschiedenen Versionen verschiedener Browser) unterschiedliche Effekte hat. Die in den Browsern verwendeten Algorithmen und Techniken werden sich wahrscheinlich im Laufe der Zeit ändern (insbesondere wenn Firefox 4 und Chrome 6 so bald herauskommen, was einen starken Schwerpunkt auf die Leistung beim Rendern von Zeichenflächen legt).
Darüber hinaus möchten Sie möglicherweise auch SVG ausprobieren, da wahrscheinlich auch ein anderer Algorithmus verwendet wird.
Viel Glück!
quelle
Ich habe das Gefühl, dass das Modul, das ich geschrieben habe, ähnliche Ergebnisse wie Photoshop liefert, da es Farbdaten bewahrt, indem es sie mittelt und keinen Algorithmus anwendet. Es ist etwas langsam, aber für mich ist es das Beste, weil alle Farbdaten erhalten bleiben.
https://github.com/danschumann/limby-resize/blob/master/lib/canvas_resize.js
Es wird nicht der nächste Nachbar genommen und keine anderen Pixel gelöscht oder eine Gruppe abgetastet und ein zufälliger Durchschnitt ermittelt. Es wird genau das Verhältnis benötigt, das jedes Quellpixel in das Zielpixel ausgeben soll. Die durchschnittliche Pixelfarbe in der Quelle ist die durchschnittliche Pixelfarbe im Ziel, was diese anderen Formeln meiner Meinung nach nicht sein werden.
Ein Beispiel für die Verwendung finden Sie unten unter https://github.com/danschumann/limby-resize
UPDATE OKT 2018 : Heutzutage ist mein Beispiel akademischer als alles andere. Webgl ist fast zu 100%, daher ist es besser, die Größe zu ändern, um ähnliche Ergebnisse zu erzielen, jedoch schneller. PICA.js macht das, glaube ich. - -
quelle
Ich habe die Antwort von @ syockit sowie den Step-Down-Ansatz in einen wiederverwendbaren Angular-Service für alle Interessierten umgewandelt: https://gist.github.com/fisch0920/37bac5e741eaec60e983
Ich habe beide Lösungen aufgenommen, weil beide ihre eigenen Vor- und Nachteile haben. Der Lanczos-Faltungsansatz bietet eine höhere Qualität auf Kosten der Langsamkeit, während der schrittweise Downscaling-Ansatz einigermaßen antialiasierte Ergebnisse liefert und erheblich schneller ist.
Anwendungsbeispiel:
quelle
Schneller und einfacher Javascript Image Resizer:
https://github.com/calvintwr/blitz-hermite-resize
Geschichte
Dies ist wirklich nach vielen Runden des Forschens, Lesens und Versuchens.
Der Resizer-Algorithmus verwendet das Hermite-Skript von @ ViliusL (Hermite-Resizer ist wirklich der schnellste und liefert eine einigermaßen gute Ausgabe). Erweitert mit den Funktionen, die Sie benötigen.
Fordert einen Mitarbeiter auf, die Größenänderung vorzunehmen, damit Ihr Browser beim Ändern der Größe nicht einfriert, im Gegensatz zu allen anderen JS-Größenänderungen.
quelle
Danke @syockit für eine tolle Antwort. Ich musste jedoch ein wenig wie folgt neu formatieren, damit es funktioniert. Möglicherweise aufgrund von DOM-Scanproblemen:
quelle
Ich habe gerade eine Seite mit Nebeneinander-Vergleichen erstellt, und wenn sich in letzter Zeit nichts geändert hat, konnte ich keine bessere Verkleinerung (Skalierung) mit Canvas im Vergleich zu einfachem CSS feststellen. Ich habe in FF6 Mac OSX 10.7 getestet. Immer noch leicht weich im Vergleich zum Original.
Ich bin jedoch auf etwas gestoßen, das einen großen Unterschied gemacht hat und das Bildfilter in Browsern verwendet, die Canvas unterstützen. Sie können Bilder ähnlich wie in Photoshop mit Unschärfe, Schärfe, Sättigung, Welligkeit, Graustufen usw. bearbeiten.
Ich habe dann ein fantastisches jQuery-Plug-In gefunden, das die Anwendung dieser Filter zum Kinderspiel macht: http://codecanyon.net/item/jsmanipulate-jquery-image-manipulation-plugin/428234
Ich wende einfach den Schärfefilter direkt nach dem Ändern der Bildgröße an, um den gewünschten Effekt zu erzielen. Ich musste nicht einmal ein Canvas-Element verwenden.
quelle
Suchen Sie nach einer anderen großartigen einfachen Lösung?
Diese Lösung verwendet den Größenänderungsalgorithmus des Browsers! :) :)
quelle