Node-vibrant: [Característica] soporte webp

Creado en 7 jul. 2017  ·  12Comentarios  ·  Fuente: Vibrant-Colors/node-vibrant

Sé que no es un trabajo fácil, pero ofrecer soporte webp sería genial.

Gracias.

help wanted wontfix

Comentario más útil

fyi: Aquí hay una implementación de ImageClass usando sharp. Es compatible con webp y svg además de todos los formatos predeterminados. Debido al problema de cambio de tamaño descrito en el comentario anterior, el código cambia el tamaño de la imagen en el método load , ignorando efectivamente todos los comandos de cambio de tamaño que provienen de node-vibrante:

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

Todos 12 comentarios

¿cómo podemos hacer eso?

Bueno, ¿cómo se convierten actualmente imágenes en matrices de píxeles?

En el navegador, lo hace <canvas> . Por lo tanto, es solo una cuestión de qué formatos admite el navegador. Consulte [browser.ts].
En node.js, se usa [jimp], ya que es una implementación de JavaScript pura. No quería introducir algunos binarios / dependencias que podrían romperse en algunas plataformas en la implementación predeterminada. Consulte [node.ts].

Node-Vibrante está diseñado para ser ampliable. El soporte de formato de imagen se proporciona a través de ImageClass s. Uno puede implementar su propio ImageClass y usarlo por set Vibrant.DefaultOpts.ImageClass = YourCustomImageClass .

Para implementar uno, uno podría

  • Amplíe la clase abstracta [ ImageBase ].
  • O implementa la interfaz [ Image ] desde cero.

La matriz de píxeles de salida debe tener el mismo formato que [ ImageData.data ]. Es decir, "una matriz unidimensional que contiene los datos en el orden RGBA, con valores enteros entre 0 y 255 (incluidos)".

Realmente es solo una cuestión de encontrar un paquete de decodificador webp para node.

¡Excelente! ¡Gracias! No soy tan bueno en TypeScript, ¡pero veré qué se puede hacer!

¡Bonito!

FYI. Estoy refactorizando el nodo vibrante en varios paquetes pequeños para la versión 3.1.0. Todas las clases de imágenes se implementan como sus propios paquetes npm.

Consulte @vibrant/image-node para ver la implementación de referencia. Sigue siendo el mismo que se describió anteriormente. Excepto que ahora solo necesitará una dependencia @vibrant/image de este proyecto, en lugar de bifurcar todo el repositorio. Con suerte, eso simplificaría las cosas.

Excelente !

He estado usando este paquete en mi bot de Discord, que está comenzando a mostrar todas sus imágenes en formato webp de forma predeterminada debido a sus muchas ventajas, por lo que esta función está comenzando a ser una gran cosa para mí. Veo una etiqueta wontfix y eso me preocupa mucho.

@nitriques, ¿ ya has hecho algo de tu "viendo lo que se puede hacer"? ¿O vas a trabajar en eso después de todo @akfish ?

@Favna No se solucionará en el paquete / repositorio principal. Pero se puede arreglar implementando un ImageClass personalizado (y publicado como un paquete npm separado). Las bibliotecas WebP para node.js (que he visto) requieren binarios externos o módulos nativos, lo que podría ser complicado de admitir en todas las plataformas. El paquete principal está diseñado para funcionar de inmediato para todas las plataformas.

Estoy trabajando en este proyecto en mi tiempo libre y esta función no es una de mis prioridades. Así que me temo que no lo arreglaré pronto.

@Favna

¿Ha hecho ya algo de su "ver lo que se puede hacer"?

Sí, y todo lo que veo son anuncios nativos.

Lo bueno es que lo necesito, por lo que podría tener tiempo para hurgar en él pronto.

¿Cómo se siente al permitir el uso de sharp en lugar de jimp a través de una bandera opcional? Dado que v0.20 sharp no requiere ningún paso de instalación adicional además de npm install en la mayoría de los sistemas. También viene con soporte webp y svg y promete ser una solución más rápida ya que se basa en módulos nativos.

Solo estoy tratando de crear un ImageClass basado en sharp, pero no será sencillo ya que resize / scaleDown debe ser sincrónico, mientras que la operación de cambio de tamaño de sharp es asincrónica.

fyi: Aquí hay una implementación de ImageClass usando sharp. Es compatible con webp y svg además de todos los formatos predeterminados. Debido al problema de cambio de tamaño descrito en el comentario anterior, el código cambia el tamaño de la imagen en el método load , ignorando efectivamente todos los comandos de cambio de tamaño que provienen de node-vibrante:

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 {}
}
¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

glomotion picture glomotion  ·  5Comentarios

catusmagnus picture catusmagnus  ·  5Comentarios

inbarshani picture inbarshani  ·  4Comentarios

daviestar picture daviestar  ·  9Comentarios

chetstone picture chetstone  ·  14Comentarios