Node.js İle Sharp Kütüphanesi Kullanarak Otomatik Görsel Filigranı Nasıl Yapılır?

Node.js İle Sharp Kütüphanesi Kullanarak Otomatik Görsel Filigranı Nasıl Yapılır?
Node.js İle Sharp Kütüphanesi Kullanarak Otomatik Görsel Filigranı Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Projeye başlamadan önce sisteminizde Node.js'in güncel bir LTS (Long Term Support) sürümünün yüklü olduğundan emin olmalısınız. Sharp kütüphanesi, C++ tabanlı libvips kütüphanesini kullandığı için kurulum sırasında sisteminizde gerekli derleme araçlarının bulunması önemlidir.

Proje dizininizi oluşturun ve gerekli paketleri yüklemek için aşağıdaki komutları terminalinizde çalıştırın:

mkdir watermark-app
cd watermark-app
npm init -y
npm install sharp

Bu adımlar, projenizi başlatacak ve görsel işleme motoru olan Sharp'ı bağımlılıklarınıza ekleyecektir. Sharp, diğer görsel işleme kütüphanelerine (Jimp veya GraphicsMagick gibi) kıyasla çok daha hızlıdır çünkü libvips kütüphanesini kullanarak görselleri parçalı (stream) olarak işler.

Adım 1: Temel Görsel İşleme Yapısını Kurma

İlk aşamada, bir ana görseli (background) ve filigran görselini (overlay) yükleyip bunları birleştiren temel fonksiyonu yazacağız. Sharp kütüphanesinde composite metodu, ana görselin üzerine başka bir görsel katmanı eklemek için kullanılır.

const sharp = require('sharp');

async function addWatermark(inputPath, outputPath, watermarkPath) {
  try {
    await sharp(inputPath)
      .composite([{ input: watermarkPath, gravity: 'southeast' }])
      .toFile(outputPath);
    console.log('Filigran başarıyla eklendi!');
  } catch (error) {
    console.error('Hata oluştu:', error);
  }
}

Burada gravity: 'southeast' parametresi, filigranın görselin sağ alt köşesine yerleştirilmesini sağlar. Sharp, otomatik olarak görsel boyutlarını hesaplar ve yerleşimi optimize eder.

Adım 2: Filigranı Özelleştirme ve Konumlandırma

Sadece sağ alt köşe her zaman yeterli olmayabilir. Bazen filigranın opaklığını (şeffaflık) ayarlamak veya belirli bir koordinata yerleştirmek isteyebilirsiniz. Sharp, composite dizisi içinde her katman için ayrı ayarlar sunar.

const addCustomWatermark = async (input, output, watermark) => {
  await sharp(input)
    .composite([{
      input: watermark,
      gravity: 'center',
      blend: 'over'
    }])
    .toFile(output);
};

blend: 'over' parametresi, filigranın ana görselin üzerinde görünmesini sağlar. Eğer filigranınızın şeffaflığını değiştirmek isterseniz, filigran görselini önceden sharp(watermark).ensureAlpha(0.5) gibi bir işlemden geçirerek şeffaflaştırabilirsiniz.

Adım 3: Görsel Boyutlandırma ve Otomatik Ölçeklendirme

Gerçek dünya senaryolarında, filigran görseli ana görselden büyük olabilir. Bu durumda filigranı ana görselin boyutuna göre dinamik olarak ölçeklendirmek gerekir. Aşağıdaki örnekte, filigranı ana görselin %20'si kadar olacak şekilde ayarlıyoruz.

const addScaledWatermark = async (input, output, watermark) => {
  const metadata = await sharp(input).metadata();
  
  await sharp(input)
    .composite([{
      input: watermark,
      gravity: 'southeast',
      // Ana görselin %20'si genişliğinde ayarla
      width: Math.round(metadata.width * 0.2)
    }])
    .toFile(output);
};

Bu yaklaşım, farklı boyutlardaki görsellerin hepsine tutarlı bir filigran yerleştirmenize olanak tanır. metadata() fonksiyonu, görselin genişlik ve yükseklik bilgilerini almamızı sağlar.

Adım 4: Performans ve Bellek Yönetimi

Sharp, büyük dosyaları işlerken oldukça verimlidir ancak binlerce görseli aynı anda işlemek sunucu belleğini zorlayabilir. Bu nedenle, işlemleri bir kuyruk (queue) yapısı ile yönetmek veya akış (stream) kullanmak en iyi pratiktir.

const fs = require('fs');

const processStream = (inputPath, outputPath, watermarkPath) => {
  const readStream = fs.createReadStream(inputPath);
  const writeStream = fs.createWriteStream(outputPath);

  readStream
    .pipe(sharp().composite([{ input: watermarkPath, gravity: 'southeast' }]))
    .pipe(writeStream);
};

Stream yapısı, dosyanın tamamını belleğe yüklemeden parça parça işlenmesini sağlar. Bu, özellikle yüksek trafikli uygulamalarda sunucu çökmesini engelleyen kritik bir yöntemdir.

Görsel İşleme Yöntemlerinin Karşılaştırması

Yöntem Avantaj Dezavantaj
Sharp (Buffer) Çok hızlı, basit Bellek yoğun olabilir
Sharp (Stream) Düşük bellek kullanımı Karmaşık hata yönetimi
Jimp Saf JS, kurulumu kolay Çok yavaş
Güvenlik Uyarısı: Kullanıcıların yüklediği görselleri işlerken mutlaka dosya türü kontrolü (MIME type) yapın. Sadece izin verilen formatları (JPEG, PNG, WebP) işleyin ve dosya ismini sunucuda rastgele bir isimle kaydederek "Path Traversal" saldırılarını önleyin.

Sıkça Sorulan Sorular

Sharp kütüphanesi SVG filigranları destekler mi?

Evet, Sharp hem PNG hem de SVG formatındaki filigranları destekler. SVG kullanmak, farklı çözünürlüklerdeki ekranlarda filigranın daha keskin görünmesini sağlar.

Filigranın opaklığını kod ile değiştirebilir miyim?

Evet, filigran görselini sharp().ensureAlpha(0.5) komutuyla işleyerek opaklığını %50 seviyesine getirebilir ve ardından ana görsele ekleyebilirsiniz.

Neden Jimp yerine Sharp tercih etmeliyim?

Sharp, libvips kütüphanesi sayesinde Jimp'e göre 5 ila 10 kat daha hızlıdır ve çok daha az CPU kullanır. Modern Node.js projelerinde performans için Sharp standarttır.

Filigranı görselin tam ortasına nasıl koyarım?

Sharp'ın gravity seçeneğine 'center' değerini atayarak filigranı görselin tam merkezine konumlandırabilirsiniz.

Büyük ölçekli uygulamalarda bu işlemi nerede yapmalıyım?

Kullanıcı deneyimini bozmamak için bu işlemleri ana iş parçacığında değil, bir "Worker Thread" veya arka plan kuyruk sistemi (BullMQ gibi) üzerinde yapmanız önerilir.

Sorumluluk Reddi: Bu rehberdeki kod örnekleri eğitim amaçlıdır. Üretim ortamına geçmeden önce tüm dosya giriş/çıkış işlemlerini güvenlik testlerinden geçirdiğinizden ve hata yakalama (try-catch) mekanizmalarını eksiksiz kurduğunuzdan emin olun.

Express.js Middleware ile Otomatik İşleme Hattı Oluşturma

Görsel işleme süreçlerini bir API uç noktasına entegre etmek, kullanıcı deneyimini iyileştirmenin en etkili yoludur. Aşağıdaki örnek, multer ile gelen dosyayı bellekte işleyip, diske yazmadan önce Sharp ile filigran ekleyen bir ara katman yapısını göstermektedir.

const express = require('express');
const multer = require('multer');
const sharp = require('sharp');

const app = express();
const upload = multer({ storage: multer.memoryStorage() });

app.post('/upload', upload.single('image'), async (req, res) => {
  try {
    const processedImage = await sharp(req.file.buffer)
      .composite([{ input: 'watermark.png', gravity: 'southeast' }])
      .jpeg({ quality: 80 })
      .toBuffer();

    // İşlenmiş görseli S3'e yükleyebilir veya diske kaydedebilirsiniz
    res.set('Content-Type', 'image/jpeg');
    res.send(processedImage);
  } catch (error) {
    res.status(500).send('Görsel işleme hatası: ' + error.message);
  }
});

Üretim Ortamında Hata Ayıklama ve İzleme

Görsel işleme süreçleri, özellikle yüksek trafikli uygulamalarda beklenmedik bellek (memory) sızıntılarına veya CPU darboğazlarına neden olabilir. Sharp, libvips kütüphanesini kullandığı için hata ayıklama süreçlerinde standart Node.js hata ayıklayıcılarından daha derinlemesine bilgiye ihtiyaç duyabilirsiniz.

İzlenmesi Gereken Metrikler

  • Event Loop Lag: Görsel işleme sırasında ana iş parçacığının ne kadar süre bloke olduğunu izleyin.
  • RSS (Resident Set Size): İşlemler sırasında bellek kullanımının sınırları aşıp aşmadığını kontrol edin.
  • Buffer Limitleri: Çok büyük boyutlu görsellerin işlenmesi sırasında sharp.cache(false) komutu ile önbelleği temizleyerek bellek kullanımını optimize edin.

Hata ayıklama için sharp.queue özelliğini kullanarak o an işlenmeyi bekleyen görsel sayısını loglayabilirsiniz:

setInterval(() => {
  console.log(`İşlem kuyruğundaki görsel sayısı: ${sharp.queue.length}`);
}, 5000);

İleri Seviye İpuçları: Dinamik Filigran ve Renk Uzayı

Bazen filigranın görselin renk tonuna göre otomatik olarak renk değiştirmesi gerekebilir. Sharp'ın modulate ve tint özellikleri ile filigranı dinamik olarak görselin kontrastına uyumlu hale getirebilirsiniz. Ayrıca, ICC profillerini kullanarak renk sapmalarını önlemek, profesyonel fotoğrafçılık uygulamaları için kritiktir.

Yöntem Avantajı Kullanım Alanı
Composite Hızlı ve basit Logo ve basit metinler
OverlayWith Daha fazla kontrol Karmaşık katmanlar
SVG Injection Vektörel kalite Responsive tasarımlar
Not: Filigran dosyanızın (PNG/SVG) her zaman orijinal görselden daha küçük olduğundan emin olun. Sharp, büyük bir filigranı küçük bir görselin üzerine yerleştirirken görseli bozabilir; bu nedenle resize metodunu filigran üzerinde de kullanmak en sağlıklı yaklaşımdır.

Sonuç

Node.js ve Sharp kütüphanesini kullanarak otomatik görsel filigranı eklemek, hem performanslı hem de ölçeklenebilir bir süreçtir. Bu rehberde öğrendiğiniz stream tabanlı işleme ve dinamik boyutlandırma teknikleri, profesyonel projelerinizin temelini oluşturacaktır. Bir sonraki adım olarak, bu işlemi bir Express.js middleware yapısına dönüştürerek, görseller sunucuya yüklendiği anda otomatik olarak filigranlanmasını sağlayabilirsiniz.

Bu yazıya tepkinizi paylaşın:
Selin Yılmaz

Zaman yönetimi ve üretkenlik ipuçları üzerine uzmanlaşmış bir içerik yazarıyım. Günlük yaşamı kolaylaştıran etkili yöntemleri okuyucularla paylaşarak hayat kalitesini artırmayı hedefliyorum.

Yorumlar (0)

Yorum Yaz