Skip to content

Image pt BR

Edgar Mesquita edited this page Aug 13, 2026 · 1 revision

Componente Image

🌐 Esta página em: English · Português

O componente Image é uma alternativa de alta performance à tag HTML <img> padrão, fortemente inspirada no Next.js. Ele ajuda a otimizar imagens para velocidade e para o ranqueamento em buscadores.

Recursos

  • Carregamento preguiçoso: por padrão, as imagens só são carregadas quando entram na viewport.
  • Prevenção de CLS: define largura e altura automaticamente para evitar saltos de layout.
  • Modos de layout: suporta dimensionamento fixo padrão ou um modo Fill para contêineres responsivos.
  • Placeholders com desfoque: suporte a placeholders de baixa resolução enquanto a imagem completa carrega.
  • Otimização de LCP: use a flag Priority para as imagens críticas acima da dobra.
  • Otimização no servidor: redimensionamento automático, conversão de formato (WebP/AVIF) e controle de qualidade pelo eQuantic.UI.Images.

Uso básico

new Image
{
    Src = "/path/to/image.jpg",
    Alt = "Description",
    Width = 800,
    Height = 600
}

Modos de layout

Fixo (padrão)

Exige Width e Height. A imagem mantém essas dimensões.

Fill

A imagem preenche o contêiner pai. O pai PRECISA ter posicionamento relative.

new Container
{
    ClassName = "relative h-64",
    Children =
    {
        new Image { Src = "/hero.webp", Fill = true }
    }
}

Placeholders

Use placeholders Blur para uma experiência de carregamento mais suave.

new Image
{
    Src = "/large.jpg",
    Width = 800,
    Height = 600,
    Placeholder = ImagePlaceholder.Blur,
    BlurDataURL = "data:image/webp;base64,..."
}

Otimização no servidor

O pacote eQuantic.UI.Images habilita a otimização de imagens no servidor, no estilo do Next.js. Quando ligada, as imagens locais são redimensionadas automaticamente, convertidas para WebP e servidas por um endpoint otimizado.

Como funciona

Componente Image (Optimize = true)
    │
    ▼ Gera as URLs do srcset
/_equantic/image?url=/images/hero.jpg&w=640&q=80
    │
    ▼ Endpoint de otimização de imagem
    ├── Valida os parâmetros (largura entre os tamanhos permitidos, qualidade 1-100)
    ├── Confere o cache em disco (obj/eQuantic/image-cache/)
    ├── Em caso de falta: redimensiona → converte o formato → cacheia → serve
    └── Negociação de conteúdo: cabeçalho Accept → WebP ou JPEG como alternativa

Configuração

1. Instale o pacote

<PackageReference Include="eQuantic.UI.Images" />

2. Registre os serviços

// Program.cs
builder.Services.AddUI(options =>
{
    options.UseImageOptimization(opts =>
    {
        opts.DefaultQuality = 80;              // 1-100, padrão: 75
        opts.Formats = ["image/webp"];         // Formatos de saída preferidos
        opts.CacheTtlSeconds = 14400;          // TTL do cache (padrão: 4 horas)
        opts.MaxSourceSize = 10 * 1024 * 1024; // Tamanho máximo da origem (padrão: 10MB)
    });
});

3. Mapeie o endpoint

app.UseStaticFiles();
app.MapUI(); // Mapeia automaticamente o endpoint /_equantic/image via UIOptions

Modos de otimização

Imagens de tamanho fixo (descritores de densidade 1x/2x)

Quando Width está definido e Fill é falso, o componente gera descritores de densidade 1x e 2x para telas retina:

new Image
{
    Src = "/images/hero.jpg",
    Alt = "Hero",
    Width = 800,
    Height = 600
}

HTML gerado:

<img
  src="/_equantic/image?url=%2Fimages%2Fhero.jpg&w=828&q=80"
  srcset="
    /_equantic/image?url=%2Fimages%2Fhero.jpg&w=828&q=80  1x,
    /_equantic/image?url=%2Fimages%2Fhero.jpg&w=1920&q=80 2x
  "
  width="800"
  height="600"
  loading="lazy"
  decoding="async"
/>

Imagens responsivas (descritores de largura)

Usando o modo Fill ou sem Width, o componente gera um srcset completo com todos os tamanhos configurados:

new Image
{
    Src = "/images/hero.jpg",
    Alt = "Full-width hero",
    Fill = true
}

HTML gerado:

<img
  src="/_equantic/image?url=%2Fimages%2Fhero.jpg&w=3840&q=80"
  srcset="/_equantic/image?url=%2Fimages%2Fhero.jpg&w=32&q=80 32w,
            /_equantic/image?url=%2Fimages%2Fhero.jpg&w=48&q=80 48w,
            ... (todos os tamanhos configurados) ...
            /_equantic/image?url=%2Fimages%2Fhero.jpg&w=3840&q=80 3840w"
  sizes="100vw"
  loading="lazy"
  decoding="async"
/>

Qualidade personalizada

Sobreponha a configuração global de qualidade por imagem:

new Image
{
    Src = "/images/background.jpg",
    Alt = "Background",
    Width = 1200,
    Height = 800,
    Quality = 50  // Qualidade menor para imagens de fundo
}

Ligar / desligar

A otimização é controlada em dois níveis:

Global (UseImageOptimization()) Por imagem (Optimize) Resultado
Ligada null (padrão) Otimizada
Ligada true Otimizada
Ligada false Não otimizada
Não chamada null (padrão) Não otimizada
Não chamada true Otimizada*

*Exige que o endpoint esteja mapeado; senão, as URLs são geradas mas não resolvem.

// Desligamento explícito (por exemplo, SVGs não precisam de otimização)
new Image
{
    Src = "/images/logo.svg",
    Alt = "Logo",
    Optimize = false
}

Segurança

  • Só imagens locais (caminhos começando com /) são otimizadas. URLs externas nunca são intermediadas.
  • Ataques de travessia de caminho (..) são bloqueados.
  • A largura tem que estar entre os tamanhos permitidos configurados (DeviceSizes + ImageSizes).
  • A qualidade tem que estar entre 1 e 100.
  • O tamanho do arquivo de origem é limitado por MaxSourceSize (padrão 10MB).

Negociação de conteúdo

O endpoint lê o cabeçalho Accept do browser e serve o melhor formato suportado:

  1. Confere os Formats configurados (ex.: ["image/avif", "image/webp"])
  2. Devolve o primeiro formato que o browser suporta
  3. Cai para JPEG se nenhum bater

Cache

  • Cache em disco: as imagens otimizadas são cacheadas em obj/eQuantic/image-cache/ (configurável)
  • Chave do cache: SHA256 de (url, largura, qualidade, formato)
  • TTL: configurável por CacheTtlSeconds (padrão: 4 horas)
  • Seguro entre threads: requisições concorrentes para a mesma imagem são deduplicadas
  • Cabeçalhos de resposta: Cache-Control: public, max-age={ttl}, Vary: Accept

Gerador de placeholder com desfoque

O serviço BlurPlaceholderGenerator cria placeholders JPEG minúsculos, de 8px de largura, como data URLs base64:

// Injete pela DI
var generator = app.Services.GetRequiredService<BlurPlaceholderGenerator>();

// Gere a partir de um arquivo
var dataUrl = await generator.GenerateFromFileAsync("wwwroot/images/hero.jpg");
// Devolve: "data:image/jpeg;base64,/9j/4AAQ..."

Opções de configuração

Propriedade Tipo Padrão Descrição
DeviceSizes int[] [640, 750, 828, 1080, 1200, 1920, 2048, 3840] Larguras permitidas para imagens do tamanho da viewport.
ImageSizes int[] [32, 48, 64, 96, 128, 256, 384] Larguras permitidas para imagens menores.
Formats string[] ["image/webp"] Formatos de saída preferidos (em ordem de prioridade).
DefaultQuality int 75 Qualidade padrão (1-100).
CacheTtlSeconds int 14400 TTL do cache em segundos (4 horas).
CacheDirectory string "obj/eQuantic/image-cache" Diretório de cache em disco.
MaxSourceSize long 10485760 Tamanho máximo da imagem de origem em bytes (10MB).

Propriedades

Propriedade Tipo Padrão Descrição
Src string - URL de origem da imagem.
Alt string - Texto alternativo para acessibilidade.
Width int? - Largura em pixels.
Height int? - Altura em pixels.
Fill bool false Se verdadeiro, preenche o contêiner pai.
Loading ImageLoading Lazy Lazy ou Eager.
Priority bool false Alta prioridade para pré-carregamento (LCP).
Placeholder ImagePlaceholder None Blur ou Empty.
BlurDataURL string? - Data URL pequena para o fundo desfocado.
ObjectFit string? "cover" Propriedade CSS object-fit (para o Fill).
Optimize bool? null Sobrepõe a configuração global de otimização.
Quality int 0 Qualidade da imagem (1-100). 0 = usa o padrão global.
SrcSet string? - srcset manual (ignorado quando otimizada).
Sizes string? - Atributo sizes manual.

Arquitetura

O pacote eQuantic.UI.Images segue o padrão de pacote autocontido:

eQuantic.UI.Core
    └── ImageOptimizationState (ponte estática)
         ↑ lido por                ↑ escrito por
eQuantic.UI.Components     eQuantic.UI.Images
    └── componente Image        ├── ImageOptimizer (SixLabors.ImageSharp)
                                ├── ImageCache (disco + SemaphoreSlim)
                                ├── ImageOptimizationMiddleware
                                ├── BlurPlaceholderGenerator
                                └── ImageExtensions (DI + endpoint)

Isso evita dependências circulares: o Core define o estado, o Components o lê, o Images o escreve.

Clone this wiki locally