Kompresowanie obrazów w Node.js za pomocą Sharp
Niepotrzebnie duże obrazy mogą prowadzić do spowolnienia czasu reakcji, zużywać nadmierną przepustowość i zapewniać powolne wrażenia użytkownikom, zwłaszcza tym korzystającym z wolniejszych połączeń. Może to skutkować wyższym współczynnikiem odrzuceń lub mniejszą liczbą konwersji.
Przed przesłaniem cyfrowych plików multimedialnych kompresja ich elementów wizualnych może pomóc złagodzić potencjalne komplikacje i zapewnić lepszy interfejs użytkownika. Pod tym względem moduł Sharp prezentuje proste i celowe rozwiązanie do osiągnięcia tego celu.
Konfigurowanie środowiska programistycznego
Aby zilustrować procedurę zmniejszania rozmiaru treści wizualnych, rozpocznij od wdrożenia funkcji przesyłania plików przy użyciu Multera. Można przyspieszyć ten proces, powielając kod z tego repozytorium GitHub.
Aby pomyślnie skonfigurować usługę przesyłania obrazów ze sklonowanego repozytorium GitHub, wykonaj następujące polecenie, aby zainstalować wszelkie niezbędne zależności:
npm install
Następnie zainstaluj Sharp, uruchamiając to polecenie:
npm install sharp
Moduł Sharp to wysokowydajna biblioteka Node.js do przetwarzania i manipulowania obrazami. Za pomocą Sharp można efektywnie zmieniać rozmiar, przycinać, obracać i wykonywać różne inne operacje na obrazach. Sharp posiada również doskonałe wsparcie dla kompresji obrazów.
Techniki kompresji dla różnych formatów obrazów
Różne formaty obrazów wykorzystują unikalne strategie kompresji, ponieważ są one dostosowane do konkretnych przypadków użycia i względów, takich jak jakość, wymiary plików i atrybuty, takie jak przezroczystość i możliwości animacji.
JPG/JPEG
JPEG, czyli standard kompresji obrazu Joint Photographic Experts Group, został specjalnie zaprojektowany do kompresji zdjęć i innych obrazów, które charakteryzują się ciągłą gradacją tonalną i kolorystyczną. Wykorzystując unikalną formę kompresji stratnej, skutecznie zmniejsza rozmiar pliku poprzez selektywne odrzucanie niektórych aspektów oryginalnych danych obrazu.
po pierwsze, zaimportuj moduł Sharp; po drugie, podaj ścieżkę do pliku obrazu lub bufor zawierający jego zawartość; po trzecie, użyj metody .jpeg
z zaimportowanej instancji Sharp; wreszcie, dołącz obiekt konfiguracyjny z atrybutem quality
ustawionym na wartość liczbową w zakresie od 0 do 100, gdzie niższe wartości reprezentują mniejsze pliki, ale gorszą jakość wizualną, podczas gdy wyższe wartości dają większe pliki o lepszej przejrzystości.
Można dostosować ten parametr do własnych wymagań.Aby osiągnąć optymalną wydajność kompresji, zaleca się utrzymywanie wartości w zakresie 50-80, dzięki czemu osiągnięta zostanie odpowiednia równowaga między rozmiarem pliku a wiernością obrazu.
Zakończ, zapisując skompresowaną reprezentację w systemie plików przy użyciu metody .toFile
, przekazując ścieżkę żądanego pliku wyjściowego jako parametr.
Na przykład:
await sharp(req.file.path)
.jpeg({ quality: 60 })
.toFile(`./images/compressed-${req.file.filename}`)
.then(() => {
console.log(`Compressed ${req.file.filename} successfully`);
});
Standardowe ustawienie jakości obrazu jest domyślnie ustawione na 80.
PNG
PNG, czyli Portable Network Graphics, to powszechnie znany format plików graficznych, który słynie z możliwości zapewnienia bezstratnej kompresji danych przy jednoczesnej obsłudze przezroczystości obrazów, co czyni go bardzo wszechstronnym i idealnym do różnych zastosowań.
Próbując skompresować obraz zapisany w formacie Portable Network Graphics (PNG) za pomocą Sharp, należy zauważyć, że proces ten ma kilka podobieństw do kompresji porównywalnego obrazu zapisanego jako plik Joint Photographic Experts Group (JPEG). Niemniej jednak, istnieją dwie charakterystyczne korekty, które należy wprowadzić podczas tej procedury.
Wykorzystanie formatu pliku PNG, w przeciwieństwie do JPEG, to sposób, w jaki firma Sharp obsługuje przetwarzanie obrazu.
Format PNG wykorzystuje nowatorskie podejście do kompresji, wykorzystując parametr “compressionLevel”, zamiast tradycyjnego ustawienia “quality”, jako sposób kontrolowania osiągniętego poziomu kompresji. Przy najniższym ustawieniu (0) algorytm zapewnia najszybszą i największą redukcję rozmiaru pliku, podczas gdy przy najwyższym ustawieniu (9) zapewnia najwolniejszą i najmniej znaczącą kompresję.
Na przykład:
await sharp(req.file.path)
.png({
compressionLevel: 5,
})
.toFile(`./images/compressed-${req.file.filename}`)
.then(() => {
console.log(`Compressed ${req.file.filename} successfully`);
});
Domyślnie wartość przypisana do poziomu kompresji jest ustawiona na 6.
Inne formaty
Sharps zapewnia również obsługę kompresji obrazów w różnych dodatkowych formatach plików, w tym:
Wykorzystanie algorytmu kompresji obrazu WebP w połączeniu z Sharpem odbywa się w podobny sposób jak wykorzystanie JPEG, z jedyną różnicą polegającą na wymogu wywołania metody webp
z instancji Sharp zamiast metody .jpeg
.
Tagged Image File Format (TIFF) wykorzystywany do kompresji obrazów w implementacji Sharp jest podobny do tego stosowanego przez JPEG, aczkolwiek z alternatywnym wywołaniem metody. Zamiast wywoływać metodę “.jpeg” w instancji Sharp, należy wywołać metodę “tiff”.
Format AVID, który odnosi się do formatu pliku obrazu AV1 używanego w kompresji obrazu przez Sharp, działa podobnie do JPEG.Jednak zamiast korzystać z metody .jpeg na instancji Sharp, należy zamiast tego zastosować metodę avif. Ponadto warto zauważyć, że domyślna wartość ustawienia jakości w formacie AVIF jest ustawiona na 50.
HEIF, skrót od High Efficiency Image File Format, wykorzystuje podobną procedurę kompresji w porównaniu do JPEG. Wymaga jednak użycia metody heif
zamiast metody .jpeg
w instancji Sharp. Dodatkowo, domyślnie AVIF ma jakość obrazu ustawioną na 50.
Kompresowanie obrazów za pomocą Sharp
Jeśli ktoś odtworzył repozytorium GitHub, konieczne jest uzyskanie dostępu do pliku “app.js” w projekcie i włączenie do niego wyżej wymienionych instrukcji importu.
const sharp = require("sharp");
const { exec } = require("child_process");
Funkcja exec
, która jest udostępniana przez moduł child_process
, umożliwia wykonywanie poleceń powłoki lub procesów zewnętrznych w aplikacji Node.js.
Funkcja ta umożliwia wykonanie polecenia, które porównuje wymiary pliku przed i po jego kompresji.
Następnie zastąpimy bieżącą obsługę POST "/single"
, włączając do niej dostarczony fragment kodu.
app.post("/upload-and-compress", upload.single("image"), async (req, res) => {
try {
if (!req.file) {
return res.status(404).send("Please upload a valid image");
}
const compressedFileName = req.file.filename.split(".")[0];
const compressedImageFilePath = `./images/${compressedFileName}-compressed.png`;
await sharp(req.file.path)
.jpeg({ quality: 50 })
.toFile(compressedImageFilePath)
.then(() => {
let sizeBeforeCompression, sizeAfterCompression;
const sizeBeforeCompressionCommand = `du -h ${req.file.path}`;
const sizeAfterCompressionCommand = `du -h ${compressedImageFilePath}`;
exec(sizeBeforeCompressionCommand, (err, stdout, stderr) => {
sizeBeforeCompression = stdout.split("\\t")[0];
exec(sizeAfterCompressionCommand, (err, stdout, stderr) => {
sizeAfterCompression = stdout.split("\\t")[0];
res.send({
message: "Image uploaded and compressed successfully",
sizeBeforeCompression,
sizeAfterCompression,
});
});
});
});
} catch (error) {
console.log(error);
}
});
Powyższa implementacja kodu obejmuje metodologię kompresji plików graficznych JPEG, jednocześnie przeprowadzając porównanie ich odpowiednich rozmiarów przed i po użyciu polecenia du
.
Polecenie du
to narzędzie uniksowe, które dostarcza informacji na temat wykorzystania dysku poprzez oszacowanie ilości miejsca zajmowanego przez pliki i katalogi w określonych katalogach. Wykorzystując flagę -h
, dane wyjściowe mogą być wyświetlane w formacie łatwo zrozumiałym dla człowieka, wskazując przestrzeń plików używaną przez poszczególne podkatalogi i ich zawartość.
Aby zainicjować działanie usługi przesyłania plików, wykonaj następującą instrukcję:
node app.js
Aby zweryfikować funkcjonalność aplikacji, możesz użyć aplikacji klienckiej Postman lub dowolnego alternatywnego narzędzia do testowania API, aby wysłać obraz JPEG do określonego punktu końcowego " /upload-and-compress>" w celu dalszego przetwarzania i kompresji.
Oczekuje się, że otrzymasz odpowiedź w następującym formacie:
{
"message": "Image uploaded and compressed successfully",
"sizeBeforeCompression": "13M",
"sizeAfterCompression": "3.1M"
}
Inne zastosowania modułu Sharp
Moduł Sharp oferuje szeroki zakres możliwości manipulacji obrazem, wykraczających poza zwykłą kompresję. Obejmują one zmianę rozmiaru, kadrowanie, obracanie i przerzucanie obrazów zgodnie z określonymi wymiarami. Ponadto umożliwia modyfikację przestrzeni kolorów, obsługę kanału alfa i konwersję między różnymi formatami plików.