Node-vibrant: [Funktion] Webp-Unterstützung

Erstellt am 7. Juli 2017  ·  12Kommentare  ·  Quelle: Vibrant-Colors/node-vibrant

Ich weiß, dass es keine leichte Arbeit ist, aber Webp-Unterstützung anzubieten wäre ziemlich cool.

Vielen Dank.

help wanted wontfix

Hilfreichster Kommentar

Zur Info: Hier ist eine ImageClass-Implementierung mit Sharp. Es unterstützt neben allen Standardformaten sowohl webp als auch svg. Aufgrund des im obigen Kommentar beschriebenen Größenänderungsproblems ändert der Code die Größe des Bildes in der Methode load und ignoriert effektiv alle Größenänderungsbefehle, die von node-vibrant stammen:

import * as sharp from "sharp";
import {ImageBase, ImageSource} from "@vibrant/image";

class SharpImage extends ImageBase {
  private _image: ImageData = undefined as any;

  async load(image: ImageSource): Promise<ImageBase> {
    if (typeof image === "string" || image instanceof Buffer) {
      const {data, info} = await sharp(image)
        .resize(200, 200, {fit: "inside", withoutEnlargement: true})
        .ensureAlpha()
        .raw()
        .toBuffer({resolveWithObject: true});
      this._image = {
        width: info.width,
        height: info.height,
        data: (data as unknown) as Uint8ClampedArray,
      };
      return this;
    } else {
      return Promise.reject(
        new Error("Cannot load image from HTMLImageElement in node environment")
      );
    }
  }
  clear(): void {}
  update(): void {}
  getWidth(): number {
    return this._image.width;
  }
  getHeight(): number {
    return this._image.height;
  }
  resize(targetWidth: number, targetHeight: number, ratio: number): void {
    // done in the load step, ignoring any maxDimension or quality options
  }
  getPixelCount(): number {
    const {width, height} = this._image;
    return width * height;
  }
  getImageData(): ImageData {
    return this._image;
  }
  remove(): void {}
}

Alle 12 Kommentare

wie können wir das machen?

Nun, wie konvertieren Sie Bilder derzeit in Pixelarrays?

Im Browser wird dies von <canvas> erledigt. Es kommt also nur darauf an, welche Formate der Browser unterstützt. Siehe [browser.ts].
In node.js wird [jimp] verwendet, da es sich um eine reine JavaScript-Implementierung handelt. Ich wollte nicht einige Binärdateien/Abhängigkeiten einführen, die auf einigen Plattformen in die Standardimplementierung einbrechen könnten. Siehe [node.ts].

node-vibrant ist erweiterbar. Die Unterstützung des Bildformats wird über ImageClass s bereitgestellt. Man kann sein eigenes ImageClass implementieren und es mit set Vibrant.DefaultOpts.ImageClass = YourCustomImageClass .

Um einen zu implementieren, könnte man

  • Erweitern Sie die abstrakte Klasse [ ImageBase ].
  • Oder implementiert die [ Image ] Schnittstelle von Grund auf neu.

Das Ausgabepixel-Array sollte das gleiche Format wie [ ImageData.data ] haben. Das ist "ein eindimensionales Array, das die Daten in der RGBA-Reihenfolge enthält, mit ganzzahligen Werten zwischen 0 und 255 (enthalten)".

Es geht wirklich nur darum, ein Webp-Decoder-Paket für den Knoten zu finden.

Groß! Danke! Ich bin nicht so gut in TypeScript, aber ich werde sehen, was getan werden kann!

Schön!

Zu Ihrer Information. Ich refaktoriere node-vibrant in mehrere kleine Pakete für Version 3.1.0. Alle Image-Klassen sind als eigene npm-Pakete implementiert.

Schauen Sie sich @vibrant/image-node für die Referenzimplementierung an. Es ist immer noch das gleiche wie oben beschrieben. Abgesehen davon, dass Sie jetzt nur noch eine @vibrant/image Abhängigkeit von diesem Projekt benötigen, anstatt das gesamte Repository zu forken. Hoffentlich würde das die Dinge vereinfachen.

Groß !

Ich habe dieses Paket in meinem Discord-Bot verwendet, der aufgrund seiner vielen Vorteile standardmäßig alle seine Bilder im Webp-Format anzeigt, sodass diese Funktion für mich eine große Sache wird. Ich sehe ein wontfix Label, das macht mir wirklich Sorgen.

@nitriques hast du schon "gesehen, was getan werden kann"? oder wirst du doch daran arbeiten @akfish ?

@Favna Es wird nicht im -repo behoben. Aber es kann repariert werden, indem eine benutzerdefinierte ImageClass implementiert wird (und als separates npm-Paket veröffentlicht wird). WebP-Bibliotheken für node.js (die ich gesehen habe) erfordern externe Binärdateien oder native Module, deren plattformübergreifende Unterstützung schwierig sein könnte. Das Hauptpaket soll out-of-box für alle Plattformen funktionieren.

Ich arbeite in meiner Freizeit an diesem Projekt und dieses Feature steht nicht ganz oben auf meiner Prioritätenliste. Daher befürchte ich, dass es so schnell nicht von mir behoben wird.

@Favna

hast du schon etwas von deinem "gesehen, was getan werden kann" gemacht?

Ja, und alles, was ich sehe, sind native Add-ons

Das Gute ist, dass ich es brauche, damit ich vielleicht bald die Zeit habe, darin herumzustöbern.

Was halten Sie davon, scharfe anstelle von jimp über eine optionale Flagge zu verwenden? Seit v0.20 erfordert Sharp auf den meisten Systemen außer npm install keine weiteren Installationsschritte. Es kommt auch mit Webp- und SVG-Unterstützung und verspricht eine schnellere Lösung zu sein, da es auf nativen Modulen basiert.

Ich versuche nur, ein Sharp-basiertes ImageClass zu erstellen, aber es wird nicht einfach sein, da resize / scaleDown synchron sein muss, während die Größenänderung von Sharp asynchron ist.

Zur Info: Hier ist eine ImageClass-Implementierung mit Sharp. Es unterstützt neben allen Standardformaten sowohl webp als auch svg. Aufgrund des im obigen Kommentar beschriebenen Größenänderungsproblems ändert der Code die Größe des Bildes in der Methode load und ignoriert effektiv alle Größenänderungsbefehle, die von node-vibrant stammen:

import * as sharp from "sharp";
import {ImageBase, ImageSource} from "@vibrant/image";

class SharpImage extends ImageBase {
  private _image: ImageData = undefined as any;

  async load(image: ImageSource): Promise<ImageBase> {
    if (typeof image === "string" || image instanceof Buffer) {
      const {data, info} = await sharp(image)
        .resize(200, 200, {fit: "inside", withoutEnlargement: true})
        .ensureAlpha()
        .raw()
        .toBuffer({resolveWithObject: true});
      this._image = {
        width: info.width,
        height: info.height,
        data: (data as unknown) as Uint8ClampedArray,
      };
      return this;
    } else {
      return Promise.reject(
        new Error("Cannot load image from HTMLImageElement in node environment")
      );
    }
  }
  clear(): void {}
  update(): void {}
  getWidth(): number {
    return this._image.width;
  }
  getHeight(): number {
    return this._image.height;
  }
  resize(targetWidth: number, targetHeight: number, ratio: number): void {
    // done in the load step, ignoring any maxDimension or quality options
  }
  getPixelCount(): number {
    const {width, height} = this._image;
    return width * height;
  }
  getImageData(): ImageData {
    return this._image;
  }
  remove(): void {}
}
War diese Seite hilfreich?
0 / 5 - 0 Bewertungen