Da SVG a PNG con Sharp: dimensioni e nitidezza
Renderizza SVG in PNG trasparenti alle dimensioni finali con Sharp. Segui un test riproducibile 1x e 2x, scopri quando conta la densità e perché ingrandire un PNG non funziona.
In questa pagina
Per un procedimento Sharp attuale, parti dall'SVG a ogni esportazione e chiama resize() con la larghezza in pixel realmente necessaria. Se ti serve una risorsa 2x, richiedi il doppio dei pixel in uscita. Non creare prima un piccolo PNG per poi ingrandirlo. Inoltre, non copiare una vecchia correzione density in ogni procedimento: il nostro test con Sharp 0.34.4 ha renderizzato gli stessi pixel con e senza una maggiore densità in ingresso.
La risposta breve
- Conserva l'SVG originale come file principale.
- Renderizza ogni dimensione PNG direttamente da quell'SVG con Sharp.
- Esamina dimensioni di uscita e canale alpha, poi visualizza il file alle dimensioni previste.
- Cambia l'SVG o indaga sul renderer se il risultato differisce ancora dalla sorgente. Un'impostazione di densità non può creare dettagli dentro una bitmap incorporata.
Renderizza un PNG 1x e 2x dall'SVG
Il costruttore Sharp accetta un file o buffer SVG e la sua API resize imposta le dimensioni di uscita. Per un'icona quadrata di 64 unità che apparirà a 256 pixel CSS, esporta un PNG di 256 pixel per l'uso 1x e uno di 512 pixel per l'uso 2x:
import sharp from "sharp";
const source = "icon.svg";
await Promise.all([
sharp(source).resize({ width: 256 }).png().toFile("icon-1x.png"),
sharp(source).resize({ width: 512 }).png().toFile("icon-2x.png"),
]);Omettere l'altezza conserva le proporzioni sorgente con il normale comportamento di ridimensionamento Sharp. Scegli larghezze di uscita effettive per la destinazione; "2x" indica dimensioni in pixel rispetto alle dimensioni CSS previste, non un attributo SVG o una promessa relativa a ogni schermo. Se vuoi vedere l'icona a 256 pixel CSS, confronta i PNG di 256 e 512 pixel a quella dimensione visualizzata e decidi se il file più grande giustifica il proprio peso.
La nostra icona originale di test dichiarava width="64" height="64" viewBox="0 0 64 64". L'abbiamo renderizzata a 64, 512 e 1.024 pixel con Sharp 0.34.4 fissato nel repository. Gli output di 512 e 1.024 pixel sono stati generati dall'SVG, avevano angoli trasparenti e centri disegnati opachi e riportavano le dimensioni richieste. Sono osservazioni relative a questo campione e questa versione, non un benchmark di tutta la grafica SVG.

La figura rende concreto il problema: una volta che il primo output è un PNG di 64 pixel, un ridimensionamento successivo interpola quei pixel. Non dispone più di tracciati da ridisegnare. I nostri risultati diretti e con densità regolata a 512 pixel erano identici nei canali RGBA grezzi di questo test. L'SVG sorgente, lo script di rendering e i metadati del risultato sono conservati nel materiale di ricerca dell'articolo.
Serve density in Sharp?
L'opzione density del costruttore Sharp controlla i DPI usati durante la lettura di un ingresso SVG o PDF; il valore predefinito documentato è 72. È distinta dalla richiesta di una larghezza finale con resize(). Potresti incontrare vecchi esempi Sharp che aumentano la densità in ingresso per evitare un ingrandimento sfocato. Quegli esempi descrivono un sintomo storico reale: l'issue Sharp #1421 riporta un SVG di 32 pixel che diventava pixelato quando ingrandito a 512 pixel nel 2018. Non dimostrano che il rimedio sia ancora necessario in un'installazione attuale.
Abbiamo testato questa esatta coppia su Sharp 0.34.4:
const direct = await sharp("icon.svg")
.resize({ width: 512 })
.png()
.toBuffer();
const densityFirst = await sharp("icon.svg", { density: 576 })
.resize({ width: 512 })
.png()
.toBuffer();Per la nostra icona vettoriale di 64 pixel, entrambi i procedimenti hanno prodotto gli stessi pixel RGBA di 512 × 512. Imposta la densità in ingresso soltanto quando uno specifico file e la versione Sharp installata dimostrano che serve, poi ripeti il confronto dopo gli aggiornamenti. Non trattare un numero DPI più alto come un interruttore universale di nitidezza. La prima domanda utile è se hai ancora geometria vettoriale nel momento in cui Sharp renderizza il PNG finale.
Se lavori anche con PDF, testa quell'ingresso separatamente: questo esperimento SVG non dimostra il comportamento dei PDF. Analogamente, withDensity() nella documentazione Sharp più recente descrive i metadati DPI di uscita; è un'operazione diversa dalla densità di rendering dell'ingresso SVG nel costruttore.
Controlla dimensioni, trasparenza e contenuto sorgente
Usa l'API dei metadati Sharp sull'output anziché dedurre le dimensioni dallo zoom di un'anteprima:
const oneX = await sharp("icon-1x.png").metadata();
const twoX = await sharp("icon-2x.png").metadata();
console.log({
oneX: [oneX.width, oneX.height, oneX.hasAlpha],
twoX: [twoX.width, twoX.height, twoX.hasAlpha],
});Per il campione quadrato qui presente, le dimensioni previste sono 256 × 256 e 512 × 512. hasAlpha indica un canale alpha, ma non dimostra che uno specifico angolo sia trasparente; esamina il file o campiona i pixel se la trasparenza conta per la consegna. Il campione aveva alpha zero negli angoli e 255 al centro in tutti gli output testati. Un rettangolo bianco dentro l'SVG verrebbe invece disegnato in ogni PNG, indipendentemente dal formato PNG.
Se un nuovo rendering grande è ancora pixelato, esamina il contenuto dell'SVG. Lo standard SVG consente un elemento <image> che incorpora o collega un'immagine raster. Un file può quindi avere estensione .svg mentre la grafica interna resta un PNG a bassa risoluzione. La nostra guida per trovare immagini raster dentro gli SVG mostra come controllare oggetti e XML. Aumentare la larghezza di uscita Sharp non può trasformare quei pixel incorporati in tracciati.
Controlla anche la destinazione. Un file di 512 pixel visualizzato a 1.024 pixel può apparire sfocato. Un visualizzatore con zoom molto oltre il 100% rivela la griglia PNG anche quando l'esportazione è corretta. Confronta alle dimensioni effettive renderizzate e sullo sfondo previsto, poi decidi se consegnare un PNG più grande o l'SVG stesso. Per il web, SVG inline e SVG in un elemento immagine offrono scelte di integrazione diverse; nessuna richiede un PNG quando la destinazione supporta SVG.
Dove è utile PerfectVector
Sharp rasterizza un SVG; non recupera tracciati modificabili da un PNG. Se la grafica originale è soltanto un'icona o un logo raster, crea ed esamina un SVG prima di questo procedimento di esportazione. La guida da icone PNG a SVG per kit UI descrive geometria coerente e controlli di consegna su una serie. Il procedimento da immagine a vettore di PerfectVector può creare un candidato SVG da grafica soltanto raster. Apri quel risultato, controlla sagoma, piccoli dettagli e presenza di tracciati reali, poi renderizza i PNG 1x e 2x dall'SVG approvato. Se possiedi già un SVG originale pulito, conservalo e usa direttamente Sharp.
FAQ
Perché l'output da SVG a PNG di Sharp appare sfocato? Controlla se il procedimento ha prima creato un piccolo PNG e poi lo ha ingrandito. Esamina quindi l'SVG per contenuti raster incorporati e confronta il PNG consegnato alle dimensioni reali di visualizzazione. Su una versione Sharp attuale, testa il rendering diretto dall'SVG alle dimensioni finali prima di aggiungere un rimedio sulla densità in ingresso.
È necessario density: 576 per un ingrandimento di otto volte?
Non era necessario per il nostro campione SVG da 64 a 512 pixel su Sharp 0.34.4: il ridimensionamento diretto e quello con densità regolata hanno prodotto pixel RGBA identici. Il tuo SVG e il renderer installato possono comportarsi diversamente, quindi testa quegli ingressi precisi anziché adottare il numero come regola.
Come creo un PNG 2x trasparente? Renderizza dall'SVG al doppio delle dimensioni CSS previste ed esporta come PNG. Conferma larghezza e altezza risultanti, poi esamina un'area non disegnata per la trasparenza. Una tela trasparente non rimuove una forma di sfondo già presente nell'SVG.
Fonti
- Sharp — Costruttore — Supporto dell'ingresso SVG e opzione
densityin ingresso. - Sharp — Ridimensionamento delle immagini — Comportamento delle dimensioni di uscita usato negli esempi.
- Sharp — Metadati in ingresso — Controlli di dimensioni e metadati alpha.
- Sharp GitHub — Issue #1421 sulla pixelatura da SVG a PNG — Sintomo storico segnalato, esplicitamente distinto dal test con la versione attuale fissata.
- Sharp — Opzioni di uscita — Distingue i più recenti metadati di densità in uscita dalla densità di rendering in ingresso.
- W3C — Contenuto incorporato SVG 2 — Spiega perché un SVG può contenere pixel raster.
Se l'originale è soltanto raster, crea un candidato SVG con PerfectVector, esamina i tracciati e usa Sharp per renderizzare il file approvato a ogni dimensione PNG richiesta.
Altro dal blog

SVG in Unity: prepara grafica per UI Toolkit o sprite
Scegli il flusso SVG in Unity per versione e destinazione. Prepara tracciati, gestisci effetti non supportati e verifica immagini UI Toolkit o sprite nel contesto.
Icone SVG Shopify: prepara un simbolo del marchio
Prepara un'icona SVG personalizzata per un tema Shopify e scegli tra risorsa immagine e snippet Liquid incorporato. Verifica tracciati, colori, dimensioni e accessibilità.