Contents

การบีบอัดรูปภาพใน Node.js ด้วย Sharp

รูปภาพขนาดใหญ่โดยไม่จำเป็นอาจทำให้เวลาตอบสนองช้าลง ใช้แบนด์วิธมากเกินไป และมอบประสบการณ์ที่เชื่องช้าให้กับผู้ใช้ โดยเฉพาะผู้ใช้ที่มีการเชื่อมต่อช้ากว่า ซึ่งอาจส่งผลให้อัตราตีกลับสูงขึ้นหรือ Conversion น้อยลง

ก่อนที่จะส่งไฟล์สื่อดิจิทัล การบีบอัดองค์ประกอบภาพอาจช่วยบรรเทาภาวะแทรกซ้อนที่อาจเกิดขึ้น และปรับปรุงอินเทอร์เฟซผู้ใช้ให้ดีขึ้น ในเรื่องนี้ โมดูล Sharp นำเสนอโซลูชันที่ง่ายและสะดวกเพื่อให้บรรลุวัตถุประสงค์นี้

การตั้งค่าสภาพแวดล้อมการพัฒนาของคุณ

เพื่ออธิบายขั้นตอนในการลดขนาดของเนื้อหาภาพ ให้เริ่มต้นด้วยการใช้ฟังก์ชันการอัพโหลดไฟล์โดยใช้ Multer อาจเร่งกระบวนการโดยการทำซ้ำโค้ดจากที่เก็บ GitHub นี้

หากต้องการตั้งค่าบริการอัพโหลดรูปภาพจากพื้นที่เก็บข้อมูล GitHub ที่โคลนได้สำเร็จ ให้ดำเนินการคำสั่งต่อไปนี้เพื่อติดตั้งการขึ้นต่อกันที่จำเป็น:

 npm install

จากนั้นติดตั้ง Sharp โดยใช้คำสั่งนี้:

 npm install sharp

โมดูล Sharp เป็นไลบรารี Node.js ประสิทธิภาพสูงสำหรับการประมวลผลและจัดการรูปภาพ คุณสามารถใช้ Sharp เพื่อปรับขนาด ครอบตัด หมุน และดำเนินการอื่นๆ กับรูปภาพได้อย่างมีประสิทธิภาพ Sharp ยังรองรับการบีบอัดภาพได้อย่างดีเยี่ยม

เทคนิคการบีบอัดสำหรับรูปแบบภาพต่างๆ

รูปแบบภาพที่แตกต่างกันใช้กลยุทธ์การบีบอัดที่เป็นเอกลักษณ์ เนื่องจากได้รับการปรับแต่งให้เหมาะกับกรณีการใช้งานเฉพาะและข้อควรพิจารณา เช่น คุณภาพ ขนาดไฟล์ และคุณลักษณะ เช่น ความโปร่งใสและความสามารถด้านภาพเคลื่อนไหว

JPG/JPEG

JPEG หรือมาตรฐานการบีบอัดภาพของ Joint Photographic Experts Group ได้รับการออกแบบมาเป็นพิเศษสำหรับการบีบอัดภาพถ่ายและภาพอื่นๆ ที่มีการไล่โทนสีและการไล่สีที่ต่อเนื่อง การใช้รูปแบบการบีบอัดแบบสูญเสียข้อมูลที่เป็นเอกลักษณ์ ช่วยลดขนาดไฟล์ได้อย่างมีประสิทธิภาพโดยการเลือกละทิ้งข้อมูลภาพต้นฉบับบางส่วน

ประการแรก นำเข้าโมดูล Sharp ประการที่สอง ระบุเส้นทางไปยังไฟล์รูปภาพหรือบัฟเฟอร์ที่มีเนื้อหา ประการที่สาม ใช้เมธอด .jpeg จากอินสแตนซ์ Sharp ที่นำเข้า สุดท้าย รวมออบเจ็กต์การกำหนดค่าที่มีแอตทริบิวต์ คุณภาพ ที่ตั้งค่าเป็นตัวเลขตั้งแต่ 0 ถึง 100 โดยที่ค่าที่ต่ำกว่าแสดงถึงไฟล์ขนาดเล็ก แต่คุณภาพของภาพไม่ดี ในขณะที่ค่าที่สูงกว่าจะทำให้ไฟล์มีขนาดใหญ่ขึ้นและมีความชัดเจนมากขึ้น

สามารถปรับพารามิเตอร์ได้ตามความต้องการเฉพาะของตน เพื่อให้บรรลุประสิทธิภาพการบีบอัดที่ดีที่สุด ขอแนะนำให้รักษาค่าไว้ภายในช่วง 50-80 ซึ่งจะทำให้ได้สมดุลที่เหมาะสมระหว่างขนาดไฟล์และความคมชัดของภาพ

สรุปโดยจัดเก็บการแสดงการบีบอัดในระบบไฟล์โดยใช้เมธอด .toFile โดยส่งผ่านพาธของไฟล์เอาต์พุตที่ต้องการเป็นพารามิเตอร์

ตัวอย่างเช่น:

 await sharp(req.file.path)
        .jpeg({ quality: 60 })
        .toFile(`./images/compressed-${req.file.filename}`)
        .then(() => {
          console.log(`Compressed ${req.file.filename} successfully`);
        });

การตั้งค่ามาตรฐานสำหรับคุณภาพของภาพตั้งไว้ที่ 80 ตามค่าเริ่มต้น

PNG

PNG หรือกราฟิกเครือข่ายแบบพกพาเป็นรูปแบบไฟล์ภาพที่ได้รับการยอมรับอย่างกว้างขวาง ซึ่งมีชื่อเสียงในด้านความสามารถในการบีบอัดข้อมูลแบบไม่สูญเสียข้อมูล ขณะเดียวกันก็สนับสนุนความโปร่งใสของภาพ ทำให้มีความหลากหลายสูงและเหมาะสำหรับการใช้งานต่างๆ

เมื่อพยายามบีบอัดภาพที่บันทึกในรูปแบบ Portable Network Graphics (PNG) โดยใช้ Sharp สิ่งสำคัญคือต้องทราบว่ากระบวนการนี้มีความคล้ายคลึงกันหลายประการกับการบีบอัดภาพที่เทียบเคียงซึ่งบันทึกเป็นไฟล์ Joint Photographic Experts Group (JPEG) อย่างไรก็ตาม มีการปรับปรุงสองประการที่ต้องทำในระหว่างขั้นตอนนี้

การใช้รูปแบบไฟล์ PNG ซึ่งต่างจาก JPEG คือวิธีที่ Sharp จัดการกับการประมวลผลภาพ

รูปแบบ PNG ใช้วิธีการใหม่ในการบีบอัดโดยใช้พารามิเตอร์"compressionLevel"แทนที่จะเป็นการตั้งค่า"คุณภาพ"แบบเดิม เป็นวิธีการควบคุมระดับการบีบอัดที่ได้รับ ที่การตั้งค่าต่ำสุด (0) อัลกอริธึมจะสร้างการลดขนาดไฟล์ที่รวดเร็วและครอบคลุมที่สุด ในขณะที่การตั้งค่าสูงสุด (9) จะให้การบีบอัดที่ช้าที่สุดและสำคัญน้อยที่สุด

ตัวอย่างเช่น:

 await sharp(req.file.path)
        .png({
          compressionLevel: 5,
        })
        .toFile(`./images/compressed-${req.file.filename}`)
        .then(() => {
          console.log(`Compressed ${req.file.filename} successfully`);
        });

ตามค่าเริ่มต้น ค่าที่กำหนดให้กับระดับการบีบอัดจะถูกตั้งไว้ที่ 6

รูปแบบอื่นๆ

Sharps ยังรองรับการบีบอัดรูปภาพในรูปแบบไฟล์เพิ่มเติมที่หลากหลาย เช่น:

การใช้อัลกอริธึมการบีบอัดภาพ WebP ร่วมกับ Sharp เป็นไปตามขั้นตอนที่คล้ายกันกับการใช้ JPEG โดยมีข้อแตกต่างเพียงอย่างเดียวคือข้อกำหนดในการเรียกใช้เมธอด webp จากอินสแตนซ์ Sharp แทนที่จะเป็นเมธอด .jpeg

รูปแบบไฟล์ภาพที่ติดแท็ก (TIFF) ที่ใช้สำหรับการบีบอัดภาพในการใช้งานของ Sharp เป็นไปตามขั้นตอนที่คล้ายคลึงกับที่ใช้โดย JPEG แม้ว่าจะใช้วิธีการอื่นก็ตาม แทนที่จะเรียกเมธอด “.jpeg” บนอินสแตนซ์ Sharp เราจะต้องเรียกใช้เมธอด “tiff” แทน

รูปแบบ AVID ซึ่งเกี่ยวข้องกับรูปแบบไฟล์ภาพ AV1 ที่ใช้ในการบีบอัดภาพโดย Sharp นั้นทำงานคล้ายกับ JPEG อย่างไรก็ตาม แทนที่จะใช้วิธี.jpeg บนอินสแตนซ์ Sharp เราต้องใช้วิธี avif แทน นอกจากนี้ เป็นที่น่าสังเกตว่าค่าเริ่มต้นสำหรับการตั้งค่าคุณภาพภายในรูปแบบ AVIF ตั้งไว้ที่ 50

HEIF ซึ่งย่อมาจาก High Efficiency Image File Format ใช้ขั้นตอนที่คล้ายกันในแง่ของการบีบอัดเมื่อเปรียบเทียบกับ JPEG อย่างไรก็ตาม ต้องใช้เมธอด heif แทนเมธอด .jpeg บนอินสแตนซ์ Sharp นอกจากนี้ ตามค่าเริ่มต้น AVIF มีการตั้งค่าคุณภาพของภาพเป็น 50

การบีบอัดภาพด้วยความคมชัด

หากใครสร้างพื้นที่เก็บข้อมูล GitHub ขึ้นมาใหม่ จำเป็นต้องเข้าถึงไฟล์ “app.js” ภายในโปรเจ็กต์และรวมคำสั่งนำเข้าที่กล่าวมาข้างต้นไว้ในนั้น

 const sharp = require("sharp");
const { exec } = require("child_process");

ฟังก์ชัน exec ซึ่งเปิดให้ใช้งานผ่านโมดูล child\_process ช่วยให้สามารถดำเนินการคำสั่งเชลล์หรือกระบวนการภายนอกภายในแอปพลิเคชัน Node.js

ฟังก์ชันนี้ช่วยให้คุณสามารถดำเนินการคำสั่งซึ่งเปรียบเทียบขนาดของไฟล์ก่อนและหลังการบีบอัด

ต่อไป เราจะแทนที่ตัวจัดการ POST'/single' ปัจจุบันโดยการรวมข้อมูลโค้ดที่ให้มาไว้ภายใน

 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);
  }
});

การใช้โค้ดที่กล่าวมาข้างต้นครอบคลุมถึงวิธีการบีบอัดไฟล์ภาพ JPEG ขณะเดียวกันก็ทำการเปรียบเทียบขนาดไฟล์ตามลำดับก่อนและหลังการใช้คำสั่ง du

คำสั่ง du เป็นยูทิลิตี้ Unix ที่ให้ข้อมูลเกี่ยวกับการใช้งานดิสก์โดยการประมาณจำนวนพื้นที่ที่ไฟล์และไดเร็กทอรีครอบครองภายในไดเร็กทอรีที่ระบุ ด้วยการใช้แฟล็ก -h เอาต์พุตสามารถแสดงในรูปแบบที่มนุษย์เข้าใจได้ง่าย โดยระบุพื้นที่ไฟล์ที่ใช้โดยไดเร็กทอรีย่อยแต่ละรายการและเนื้อหาตามลำดับ

เพื่อเริ่มการทำงานของบริการถ่ายโอนไฟล์ของคุณ ให้ปฏิบัติตามคำสั่งต่อไปนี้:

 node app.js

เพื่อตรวจสอบฟังก์ชันการทำงานของแอปพลิเคชันของคุณ คุณสามารถใช้แอปไคลเอ็นต์บุรุษไปรษณีย์หรือเครื่องมือทดสอบ API ทางเลือกใดๆ ที่คุณเลือกเพื่อส่งภาพ JPEG ไปยังตำแหน่งข้อมูลที่ระบุ “” เพื่อการประมวลผลและการบีบอัดเพิ่มเติม

คาดว่าคุณจะได้รับการตอบกลับที่คล้ายกับรูปแบบต่อไปนี้:

 {
  "message": "Image uploaded and compressed successfully",
  "sizeBeforeCompression": "13M",
  "sizeAfterCompression": "3.1M"
}

การใช้งานอื่นๆ ของ Sharp Module

โมดูล Sharp นำเสนอความสามารถในการจัดการภาพที่ครอบคลุมมากกว่าแค่การบีบอัด ซึ่งรวมถึงการปรับขนาด การครอบตัด การหมุน และการพลิกรูปภาพตามขนาดที่ระบุ นอกจากนี้ยังช่วยให้สามารถปรับเปลี่ยนพื้นที่สี การทำงานของช่องอัลฟา และการแปลงระหว่างรูปแบบไฟล์ต่างๆ