LeanImg

Πώς μπορώ να μετατρέψω ένα SVG σε PNG χωρίς να χάσω τις γραμματοσειρές;

Γιατί η έξοδος SVG σε PNG καταλήγει σε 2x το δηλωμένο μέγεθος και γιατί το sandbox του προγράμματος περιήγησης απορρίπτει σιωπηλά τις εξωτερικές γραμματοσειρές και τις συνδεδεμένες εικόνες κατά τη διάρκεια της απόδοσης.

Ένα SVG δεν έχει εικονοστοιχεία μέσα του. Είναι XML: διαδρομές, γεμίσματα, ένα viewBox και ίσως ένα στοιχείο <text> που ονομάζει μια γραμματοσειρά που το αρχείο δεν περιέχει πραγματικά. Η ραστεροποίηση του σε PNG σημαίνει την επιλογή ενός πλέγματος εικονοστοιχείων και την ζωγραφική αυτών των σχημάτων πάνω του, οπότε δύο πράγματα αποφασίζουν αν σας αρέσει το αποτέλεσμα. Πόσα εικονοστοιχεία ζητήσατε και τι επιτράπηκε στον renderer να φορτώσει ενώ ζωγράφιζε.

Εκτελούμε αυτή την απόδοση μέσα στο πρόγραμμα περιήγησής σας. Το αρχείο πηγαίνει σε μια διεύθυνση blob URL, ένα στοιχείο <img> το φορτώνει, το πρόγραμμα περιήγησης το ζωγραφίζει σε ένα OffscreenCanvas και ένας κωδικοποιητής WebAssembly γράφει το PNG. Αυτή η εφαρμογή δεν έχει διαδρομές API και καμία ενέργεια server, οπότε ένα μη δημοσιευμένο λογότυπο δεν κάθεται ποτέ σε έναν προσωρινό κάδο περιμένοντας μια διαγραφή cron. Οι περισσότεροι μετατροπείς SVG σε PNG ανεβάζουν πρώτα και υπόσχονται καθαρισμό αργότερα. Ο δικός μας δεν στέλνει ποτέ τα bytes οπουδήποτε, που είναι το όλο νόημα του μοντέλου ιδιωτικότητάς μας.

Τι συμβαίνει πραγματικά όταν ένα πρόγραμμα περιήγησης ραστεροποιεί ένα SVG;

Το SVG σας παραδίδεται σε ένα στοιχείο <img>, και αυτή η λεπτομέρεια καθοδηγεί όλα τα υπόλοιπα σε αυτή τη σελίδα. Ένα SVG που φορτώνεται ως εικόνα εκτελείται σε μια περιορισμένη λειτουργία επεξεργασίας όπου τα σενάρια δεν εκτελούνται και οι εξωτερικές αναφορές δεν ανακτώνται, κάτι που οι κανόνες συμμόρφωσης SVG 2 ορίζουν ως ασφαλείς τρόπους επεξεργασίας. Μόλις η φόρτωση επιλυθεί, το ζωγραφίζουμε με drawImage σε ένα OffscreenCanvas, διαβάζουμε τα εικονοστοιχεία πίσω, κωδικοποιούμε με @jsquash/png και στη συνέχεια εκτελούμε το oxipng στο επίπεδο 3 πάνω από τα bytes. Αυτό το βήμα είναι χωρίς απώλειες. Το alpha επιβιώνει σε όλη τη διαδρομή, οπότε ένα διαφανές λογότυπο βγαίνει διαφανές.

Ποιο μέγεθος θα έχει πραγματικά το PNG;

Ο μετατροπέας μας αποδίδει σε διπλάσιο του εγγενή μεγέθους του SVG. Ένα SVG 500x500 βγαίνει 1000x1000. Η διπλασιασμένη διάσταση σας προσφέρει ένα αρχείο ποιότητας retina δωρεάν, και είναι επίσης αυτό που οι άνθρωποι παραπατούν όταν μια προδιαγραφή απαιτεί ακριβή αριθμό εικονοστοιχείων. Αν το πρόγραμμα περιήγησης αναφέρει κανένα χρήσιμο εγγενές μέγεθος, υποκαθιστούμε με 1024x1024 πριν τον διπλασιασμό, οπότε το PNG καταλήγει σε 2048x2048. Οι προδιαγραφές CSS Images καλύπτουν γιατί ένα μέγεθος μπορεί να λείπει εξαρχής: ένα αντικατεστημένο στοιχείο χωρίς εγγενές πλάτος ή ύψος επιστρέφει σε ένα προεπιλεγμένο μέγεθος αντικειμένου, και ένα viewBox από μόνο του παρέχει μια αναλογία χωρίς μέγεθος συνδεδεμένο. Έτσι, ορίστε πλάτος και ύψος στο ρίζα <svg> στο μισό του στόχου σας. 256 εισερχόμενα, 512 εξερχόμενα.

Τα μεγέθη εξόδου ακολουθούν άμεσα τον κανόνα 2x στον κινητήρα μετατροπής μας.
Τι δηλώνει το ρίζα <svg>PNG που γράφουμε
width="500" height="500"1000 x 1000
width="256" height="256"512 x 512
width="64" height="64" (ένα εικονίδιο)128 x 128, συνήθως πολύ μικρό
Κανένα χρήσιμο εγγενές μέγεθος2048 x 2048 (1024 εναλλακτική, διπλασιασμένο)

Γιατί το κείμενό μου βγήκε σε λάθος γραμματοσειρά;

Αυτή είναι η πιο κοινή κατα complaint και δεν είναι σφάλμα στον μετατροπέα. Ένας κανόνας @font-face που δείχνει σε μια διεύθυνση .woff2 μετράει ως εξωτερική αναφορά, οπότε η ασφαλής λειτουργία αποκλείει αυτή τη φόρτωση πριν ξεκινήσει. Οι γραμματοσειρές που φορτώνονται από τη σελίδα γύρω από την εικόνα δεν φτάνουν μέσα ούτε, επειδή ένα SVG σε ένα <img> είναι ένα ξεχωριστό έγγραφο που κάνει τη δική του ανάλυση γραμματοσειρών. Αυτό που παίρνετε είναι ό,τι μπορεί να ταιριάξει η μηχανή από τη λίστα γραμματοσειρών, που σε ένα λάπτοπ αναθεωρητή σημαίνει μια εναλλακτική που ποτέ δεν επιλέξατε. Η λύση είναι να σταματήσετε να στέλνετε κείμενο ως κείμενο. Το Illustrator το ονομάζει Type > Create Outlines. Το Inkscape το ονομάζει Path > Object to Path. Και οι δύο μετατρέπουν κάθε γλύφο σε μια διαδρομή, το αρχείο μεγαλώνει λίγο και η απόδοση σταματά να εξαρτάται από τη μηχανή.

Γιατί η φωτογραφία μέσα στο SVG μου λείπει;

Ο ίδιος κανόνας, διαφορετικό σύμπτωμα. Αν το SVG σας τραβάει μια bitmap μέσω ενός στοιχείου <image> με απόλυτη διεύθυνση https, αυτή η διεύθυνση δεν ανακτάται, και το PNG επιστρέφει με μια τρύπα όπου θα έπρεπε να είναι η φωτογραφία. Ένα data: URI λειτουργεί καλά, επειδή δεν υπάρχει αίτημα δικτύου που να αποκλείεται. Υπάρχει και δεύτερος λόγος για να ενσωματώσετε: μια bitmap διασυνοριακή ζωγραφισμένη σε έναν καμβά μολύνει και η ανάγνωση των εικονοστοιχείων πίσω ρίχνει ένα SecurityError. Αυτή η αποτυχία τουλάχιστον ανακοινώνει τον εαυτό της. Μια αποκλεισμένη αναφορά είναι σιωπηλή, κάτι που κοστίζει στους ανθρώπους ένα απόγευμα. Ανοίξτε το αρχείο σε έναν επεξεργαστή κειμένου και αναζητήστε http πριν το μετατρέψετε.

Μπορώ να μετατρέψω ένα PNG πίσω σε SVG;

Όχι, και δεν προσποιούμαστε διαφορετικά. Ο μετατροπέας μας αποκωδικοποιεί SVG και δεν μπορεί να το κωδικοποιήσει: οι κωδικοποιητές στην κατασκευή γράφουν JPEG, PNG, WebP, AVIF και PDF, και κανένα από τα 24 ζεύγη σε 11 μορφές δεν έχει SVG ως στόχο. Η μετάβαση από εικονοστοιχεία πίσω σε διαδρομές είναι ανίχνευση, μια μηχανή που μαντεύει πού ανήκουν οι άκρες, και ένα ανιχνευμένο λογότυπο σπάνια είναι αρκετά κοντά για να σταλεί. Επαναεξάγετε από το πρωτότυπο αν το έχετε ακόμα. Αν αυτό που πραγματικά χρειάζεστε είναι η ραστεροποίηση σε μεγαλύτερο μέγεθος, ο upscaler μας εκτελεί το Real-ESRGAN και πάντα γράφει PNG: πήρε ένα αρχείο 400x269 σε 1600x1076 σε 4x.

Πώς μπορώ να μετατρέψω ένα SVG σε ένα σύνολο favicon;

Ο γεννήτορας εικονιδίων δέχεται SVG απευθείας, το οποίο ο συμπιεστής, ο μετατροπέας και ο κοπτήρας δεν δέχονται: αυτοί οι τρεις δέχονται μόνο JPEG, PNG, WebP, AVIF και GIF. Αποδίδει το SVG σας σε έναν τετράγωνο καμβά με μέγεθος το μεγαλύτερο από τις δύο διαστάσεις του ή 512 εικονοστοιχεία, όποιο κερδίζει, έτσι ένα εικονίδιο 64x64 εξακολουθεί να παίρνει έναν καμβά 512 για να μειωθεί. Βγαίνουν επτά αρχεία: favicon.ico που περιέχει 16, 32 και 48, favicon-16x16.png, favicon-32x32.png, ένα 180px apple-touch-icon.png, android-chrome-192x192.png, android-chrome-512x512.png και site.webmanifest. Γιατί αυτό το ένα .ico εξακολουθεί να κερδίζει τα 4,6 KB είναι μια ξεχωριστή συζήτηση. Ένα αρχείο τη φορά, όριο 10 MB. Ο μετατροπέας είναι το εργαλείο παρτίδας: 10 αρχεία και 50 MB ανά εκτέλεση.

Τα επτά αρχεία που παράγονται από τον γεννήτορα εικονιδίων, καταχωρημένα με τα μεγέθη τους, δίπλα στις ετικέτες HTML που πρέπει να επικολληθούν σε μια κεφαλή σελίδας
Η έξοδος επτά αρχείων, συν το HTML snippet. Αυτή η εκτέλεση χρησιμοποίησε ένα PNG 900x606 ως πηγή; ένα SVG παράγει το ίδιο σύνολο αρχείων.

Πρέπει να συμπιέσω το PNG μετά;

Συνήθως, και η λειτουργία έχει μεγαλύτερη σημασία από οποιοδήποτε ρυθμιστικό. Σε ένα διαφανές PNG 942,4 KB σε 900x606, η χωρίς απώλειες διαδρομή (oxipng επίπεδο 3) βγήκε 383,9 KB, μια μείωση 59% με κάθε εικονοστοιχείο να είναι ταυτόσημο με την είσοδο. Η διαδρομή παλέτας (imagequant) πήρε το ίδιο αρχείο σε 98,3 KB, μια μείωση 90%, μειώνοντάς το σε 256 χρώματα. Η επίπεδη διανυσματική τέχνη είναι η καλύτερη περίπτωση για τη λειτουργία παλέτας, καθώς ένα λογότυπο με έξι γεμίσματα δεν έχει τίποτα σαν 256 χρώματα να παραχωρήσει. Η συμπίεση αφαιρεί επίσης όλα τα μεταδεδομένα. Εκτελέστε και τις δύο στο συμπιεστή και κρατήστε όποια αντέχει.

Κάντε αυτό το επόμενο: ανοίξτε το SVG σε έναν επεξεργαστή κειμένου, αναζητήστε http για να πιάσετε τις συνδεδεμένες γραμματοσειρές και εικόνες, περιγράψτε οποιοδήποτε ζωντανό κείμενο, στη συνέχεια ορίστε πλάτος και ύψος στο ρίζα <svg> στο μισό του στόχου σας και ρίξτε το στο /convert/svg-to-png. Αν το PNG προορίζεται για μια ιστοσελίδα, στείλτε το κατευθείαν στον συμπιεστή, και το PNG σε σύγκριση με τα νούμερα WebP για ένα αρχείο με διαφάνεια σας λέει αν πρέπει να αλλάξετε μορφή καθόλου. Αν προορίζεται για έγγραφο, οι σημειώσεις μας για JPG σε PDF καλύπτουν το μέγεθος σελίδας που καταλήγει ένα μετατραπέν αρχείο.