Node-vibrant: [Fonctionnalité] prise en charge webp

Créé le 7 juil. 2017  ·  12Commentaires  ·  Source: Vibrant-Colors/node-vibrant

Je sais que ce n'est pas un travail facile, mais offrir un support webp serait plutôt cool.

Merci.

help wanted wontfix

Commentaire le plus utile

fyi: Voici une implémentation ImageClass utilisant sharp. Il prend en charge à la fois webp et svg en plus de tous les formats par défaut. En raison du problème de redimensionnement décrit dans le commentaire ci-dessus, le code redimensionne l'image dans la méthode load , ignorant effectivement toutes les commandes de redimensionnement provenant de node-vibrant :

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

Tous les 12 commentaires

Comment peut-on faire ça?

Eh bien, comment convertissez-vous actuellement des images en tableaux de pixels ?

Dans le navigateur, c'est fait par <canvas> . Il s'agit donc simplement des formats pris en charge par le navigateur. Voir [browser.ts].
Dans node.js, [jimp] est utilisé, car il s'agit d'une implémentation JavaScript pure. Je ne voulais pas introduire des binaires/dépendances qui pourraient se briser sur certaines plates-formes dans l'implémentation par défaut. Voir [node.ts].

node-vibrant est conçu pour être extensible. La prise en charge du format d'image est fournie via ImageClass s. On peut implémenter son propre ImageClass et l'utiliser par set Vibrant.DefaultOpts.ImageClass = YourCustomImageClass .

Pour en mettre un en œuvre, on pourrait

  • Étendre la classe abstraite [ ImageBase ].
  • Ou implémente l'interface [ Image ] à partir de zéro.

Le tableau de pixels de sortie doit être au même format que [ ImageData.data ]. C'est "un tableau à une dimension contenant les données dans l'ordre RGBA, avec des valeurs entières comprises entre 0 et 255 (inclus)".

C'est vraiment juste une question de trouver un package de décodeur webp pour node.

Super! Merci! Je ne suis pas très bon en TypeScript, mais je vais voir ce qu'on peut faire !

Joli!

POUR VOTRE INFORMATION. Je refactorise node-vibrant en plusieurs petits packages pour la version 3.1.0. Toutes les classes d'images sont implémentées en tant que leurs propres packages npm.

Consultez @vibrant/image-node pour la mise en œuvre de référence. C'est toujours le même que décrit ci-dessus. Sauf que maintenant, vous n'aurez besoin que d'une seule dépendance @vibrant/image de ce projet, au lieu de forker l'intégralité du référentiel. Espérons que cela simplifierait les choses.

Super !

J'utilise ce package dans mon bot Discord qui commence à afficher toutes ses images au format webp par défaut en raison de ses nombreux avantages. Cette fonctionnalité commence donc à être une chose énorme pour moi. Je vois une étiquette wontfix donc ça m'inquiète vraiment.

@nitriques avez-vous déjà fait l'un de vos "voir ce qui peut être fait" ? ou allez-vous y travailler après tout @akfish ?

@Favna Cela ne sera pas corrigé dans le package/

Je travaille sur ce projet pendant mon temps libre et cette fonctionnalité n'est pas en haut de ma liste de priorités. J'ai donc peur que ce ne soit pas réglé par moi de si tôt.

@Favna

avez-vous déjà fait l'un de vos « voir ce qui peut être fait » ?

Oui et tout ce que je vois, ce sont des ad-dons natifs

La bonne chose est que j'en ai besoin, donc j'aurai peut-être le temps d'en faire le tour bientôt.

Que pensez-vous de l'autorisation d'utiliser sharp au lieu de jimp via un indicateur facultatif ? Depuis la v0.20, sharp ne nécessite aucune étape d'installation supplémentaire en plus de npm install sur la plupart des systèmes. Il est également livré avec le support webp et svg et promet d'être une solution plus rapide car il est basé sur des modules natifs.

J'essaie juste de créer un ImageClass basé sur sharp, mais ça ne va pas être simple car resize / scaleDown doit être synchrone, alors que l'opération de redimensionnement de sharp est asynchrone.

fyi: Voici une implémentation ImageClass utilisant sharp. Il prend en charge à la fois webp et svg en plus de tous les formats par défaut. En raison du problème de redimensionnement décrit dans le commentaire ci-dessus, le code redimensionne l'image dans la méthode load , ignorant effectivement toutes les commandes de redimensionnement provenant de node-vibrant :

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 {}
}
Cette page vous a été utile?
0 / 5 - 0 notes