Node-vibrant: [Recurso] suporte webp

Criado em 7 jul. 2017  ·  12Comentários  ·  Fonte: Vibrant-Colors/node-vibrant

Eu sei que não é um trabalho fácil, mas oferecer suporte webp seria muito legal.

Obrigado.

help wanted wontfix

Comentários muito úteis

fyi: Aqui está uma implementação de ImageClass usando sharp. Ele suporta webp e svg, além de todos os formatos padrão. Devido ao problema de redimensionamento descrito no comentário acima, o código redimensiona a imagem no método load , ignorando efetivamente todos os comandos de redimensionamento que vêm 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 {}
}

Todos 12 comentários

Como podemos fazer isso?

Bem, como você atualmente converte imagens em matrizes de pixels?

No navegador, é feito por <canvas> . Portanto, é apenas uma questão de quais formatos o navegador suporta. Veja [browser.ts].
Em node.js, [jimp] é usado, pois é uma implementação JavaScript pura. Eu não queria introduzir alguns binários / dependências que podem quebrar em algumas plataformas na implementação padrão. Veja [node.ts].

node-vibrant foi projetado para ser extensível. O suporte ao formato de imagem é fornecido por ImageClass s. Pode-se implementar seu próprio ImageClass e usá-lo ao definir Vibrant.DefaultOpts.ImageClass = YourCustomImageClass .

Para implementar um, pode-se

  • Estenda a classe abstrata [ ImageBase ].
  • Ou implementa a interface [ Image ] do zero.

A matriz de pixels de saída deve ter o mesmo formato de [ ImageData.data ]. Isso é "uma matriz unidimensional contendo os dados na ordem RGBA, com valores inteiros entre 0 e 255 (incluídos)".

É realmente apenas uma questão de encontrar um pacote de decodificador webp para o nó.

Excelente! obrigado! Não sou muito bom em TypeScript, mas verei o que pode ser feito!

Agradável!

PARA SUA INFORMAÇÃO. Estou refatorando node-vibrant em vários pequenos pacotes para a versão 3.1.0. Todas as classes de imagem são implementadas como seus próprios pacotes npm.

Confira @vibrant/image-node para implementação de referência. Ainda é o mesmo descrito acima. Exceto que agora você só precisará de uma dependência @vibrant/image deste projeto, em vez de bifurcar todo o repositório. Esperançosamente, isso simplificaria as coisas.

Excelente !

Estou usando este pacote no meu bot Discord, que está começando a exibir todas as suas imagens no formato webp por padrão devido às suas muitas vantagens, então esse recurso está começando a ser um grande diferencial para mim. Vejo um rótulo wontfix , o que realmente me preocupa.

@nitriques , você já fez alguma de suas "vendo o que pode ser feito"? ou você vai trabalhar nisso depois de tudo @akfish ?

@Favna Não será corrigido no pacote principal / repo. Mas é corrigível implementando uma ImageClass personalizada (e publicada como um pacote npm separado). As bibliotecas WebP para node.js (que eu vi) exigem binários externos ou módulos nativos, o que pode ser complicado de suportar em todas as plataformas. O pacote principal deve funcionar pronto para uso em todas as plataformas.

Estou trabalhando neste projeto em meu tempo livre e esse recurso não está no topo da minha lista de prioridades. Portanto, temo que não seja consertado por mim tão cedo.

@Favna

você já fez algum de seus "vendo o que pode ser feito"?

Sim e tudo o que vejo são anúncios nativos

A coisa boa é que eu preciso disso, então terei tempo para vasculhar em breve.

O que você acha de permitir o uso de sharp em vez de jimp por meio de uma bandeira opcional? Desde a v0.20 sharp não requer nenhuma etapa de instalação adicional além de npm install na maioria dos sistemas. Ele também vem com suporte a webp e svg e promete ser uma solução mais rápida por ser baseado em módulos nativos.

Estou apenas tentando criar um ImageClass baseado em sharp, mas não vai ser direto, pois resize / scaleDown precisa ser síncrono, enquanto a operação de redimensionamento de sharp é assíncrona.

fyi: Aqui está uma implementação de ImageClass usando sharp. Ele suporta webp e svg, além de todos os formatos padrão. Devido ao problema de redimensionamento descrito no comentário acima, o código redimensiona a imagem no método load , ignorando efetivamente todos os comandos de redimensionamento que vêm 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 {}
}
Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

amirping picture amirping  ·  6Comentários

lucafaggianelli picture lucafaggianelli  ·  9Comentários

catusmagnus picture catusmagnus  ·  5Comentários

daviestar picture daviestar  ·  9Comentários

stelasido picture stelasido  ·  15Comentários