Python İle Pillow Kütüphanesi Kullanarak Toplu Resim Boyutlandırma Nasıl Yapılır?

Python İle Pillow Kütüphanesi Kullanarak Toplu Resim Boyutlandırma Nasıl Yapılır?
Python İle Pillow Kütüphanesi Kullanarak Toplu Resim Boyutlandırma Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Çalışmaya başlamadan önce sisteminizde Python 3.10 veya daha yeni bir sürümün yüklü olduğundan emin olmalısınız. Pillow kütüphanesi, görüntü işleme süreçlerinde yüksek performanslı C kütüphanelerini temel alır. Kurulum için terminal veya komut satırını kullanacağız.

Öncelikle sanal ortam (virtual environment) oluşturmanız, bağımlılıkları projenize özel tutmak için en iyi pratiktir. Aşağıdaki komutları sırasıyla uygulayın:

# Sanal ortam oluşturma
python -m venv venv

# Windows için aktivasyon
venv\Scripts\activate

# Linux/macOS için aktivasyon
source venv/bin/activate

# Pillow kütüphanesini yükleme
pip install Pillow

Bu adımlardan sonra pip list komutunu çalıştırarak Pillow paketinin yüklü olup olmadığını doğrulayın. Eğer kütüphane listeleniyorsa, kod yazmaya hazırsınız demektir.

Adım Adım Toplu Resim Boyutlandırma Mantığı

Toplu boyutlandırma işlemi üç temel aşamadan oluşur: Hedef dizindeki dosyaları listelemek, her bir dosyayı açmak ve yeniden boyutlandırarak kaydetmek. os modülü dosya sistemi işlemleri için, PIL.Image modülü ise görüntü işleme için kullanılır.

Aşağıdaki kod örneği, bir klasördeki tüm .jpg dosyalarını bulur ve bunları 800x600 piksel boyutuna getirir:

import os
from PIL import Image

def toplu_boyutlandir(kaynak_klasor, hedef_klasor, boyut):
    if not os.path.exists(hedef_klasor):
        os.makedirs(hedef_klasor)
    
    for dosya_adi in os.listdir(kaynak_klasor):
        if dosya_adi.lower().endswith(('.png', '.jpg', '.jpeg')):
            yol = os.path.join(kaynak_klasor, dosya_adi)
            img = Image.open(yol)
            img = img.resize(boyut)
            img.save(os.path.join(hedef_klasor, dosya_adi))
            print(f"{dosya_adi} başarıyla boyutlandırıldı.")

# Kullanım
toplu_boyutlandir('girdiler', 'cikti', (800, 600))

Bu kodda os.makedirs kullanarak hedef klasörün varlığını kontrol ediyoruz. Eğer yoksa otomatik oluşturuyoruz. endswith metodu ile sadece görsel formatındaki dosyaları işleme alarak hata payını düşürüyoruz.

Görüntü Kalitesini Koruma ve Boyutlandırma Teknikleri

Görselleri yeniden boyutlandırırken, özellikle küçültme işlemlerinde "aliasing" (dişlenme/bozulma) sorunları yaşanabilir. Pillow, Resampling filtresi ile bu sorunu çözer. 2026 itibarıyla en iyi sonuç veren filtre LANCZOS filtresidir.

Aşağıdaki örnekte kaliteyi koruyarak boyutlandırma işlemini güncelliyoruz:

from PIL import Image

def kaliteli_boyutlandir(dosya_yolu, cikti_yolu, genislik, yukseklik):
    with Image.open(dosya_yolu) as img:
        # LANCZOS filtresi yüksek kaliteli ölçeklendirme sağlar
        img_resized = img.resize((genislik, yukseklik), Image.Resampling.LANCZOS)
        img_resized.save(cikti_yolu, optimize=True, quality=85)

# Tekil kullanım örneği
kaliteli_boyutlandir('input.jpg', 'output.jpg', 1024, 768)

optimize=True parametresi, dosya boyutunu kaliteden ödün vermeden küçültmek için kullanılır. quality=85 değeri, genellikle görsel kalite ile dosya boyutu arasındaki en ideal dengeyi sağlar.

En-Boy Oranını Korumak (Aspect Ratio)

Resimleri sadece genişlik ve yükseklik vererek zorla boyutlandırmak, görsellerin basık veya yayvan görünmesine neden olur. Gerçek dünya projelerinde en-boy oranını korumak zorunludur. Bunu yapmak için mevcut oranı hesaplamalıyız.

def oranli_boyutlandir(img, max_genislik):
    genislik_orani = (max_genislik / float(img.size[0]))
    yukseklik_orani = int((float(img.size[1]) * float(genislik_orani)))
    return img.resize((max_genislik, yukseklik_orani), Image.Resampling.LANCZOS)

# Kullanım
with Image.open('foto.jpg') as img:
    yeni_img = oranli_boyutlandir(img, 500)
    yeni_img.save('yeni_foto.jpg')

Bu yöntemle, genişliği 500 piksel olan tüm resimlerin yükseklikleri, orijinal oranları bozulmadan otomatik olarak hesaplanır.

Hata Yönetimi ve Güvenlik Uyarıları

Kritik Uyarı: Kullanıcıdan alınan dosya yollarını doğrudan işlemek, "Path Traversal" (yol geçişi) saldırılarına davetiye çıkarabilir. Dosya yollarını her zaman os.path.basename ile temizleyin ve sadece izin verilen dizinlerde işlem yapın. Ayrıca, büyük boyutlu görsellerin (örneğin 100MB+ tiff dosyaları) bellek tüketimini (RAM) artırabileceğini unutmayın.

Hata yönetimi için try-except bloklarını kullanmak, scriptinizin bir hata ile karşılaştığında tamamen durmasını engeller.

import os
from PIL import Image

def guvenli_toplu_islem(klasor):
    for dosya in os.listdir(klasor):
        try:
            dosya_yolu = os.path.join(klasor, dosya)
            with Image.open(dosya_yolu) as img:
                # İşlemler...
                pass
        except Exception as e:
            print(f"{dosya} işlenirken hata oluştu: {e}")

# Hataları loglayarak ilerlemek profesyonel bir yaklaşımdır.

Karşılaştırma: Boyutlandırma Yöntemleri

Yöntem Avantajı Dezavantajı
resize() Hızlı ve basit. En-boy oranı korunmazsa bozulma olur.
thumbnail() Oranı otomatik korur, bellek dostudur. Sadece küçültme yapar, büyütmez.
ImageOps.fit() Merkezden kırparak tam boyut sağlar. Görselin kenarlarından veri kaybı olabilir.

Sıkça Sorulan Sorular

Pillow ile çok büyük görselleri işlerken bellek hatası alıyorum, ne yapmalıyım?

Büyük görseller için Image.MAX_IMAGE_PIXELS sınırını kontrol edin veya görselleri parça parça (chunk) okuyun. Ayrıca Image.draft() metodunu kullanarak düşük çözünürlüklü önizlemelerle çalışabilirsiniz.

Neden thumbnail yerine resize kullanmalıyım?

thumbnail() metodu, görüntüyü orijinal en-boy oranını koruyarak belirtilen kutunun içine sığdırır. resize() ise verdiğiniz değerlere göre görüntüyü esnetir. Eğer tam boyut (örneğin 800x800) zorunlu ise resize() tercih edilmelidir.

Kodum neden bazı .png dosyalarını işleyemiyor?

PNG dosyaları bazen "RGBA" (şeffaflık) modunda olabilir. Eğer JPEG olarak kaydediyorsanız, şeffaflık kanalı hataya neden olur. img = img.convert("RGB") komutu ile önce RGB moduna çevirmeniz gerekir.

Toplu işlem sırasında orijinal dosyalarımı nasıl koruyabilirim?

Her zaman orijinal dosyalarınızı ayrı bir "kaynak" klasöründe tutun ve çıktıları farklı bir "hedef" klasörüne kaydedin. Asla orijinal dosyaların üzerine yazma (overwrite) işlemi yapmayın.

Pillow dışında başka bir kütüphane kullanmalı mıyım?

Eğer çok yüksek performans gerektiren (milyonlarca görsel) bir projeniz varsa, OpenCV veya Wand (ImageMagick wrapper) kütüphanelerini inceleyebilirsiniz. Ancak standart ihtiyaçlar için Pillow en iyi dokümantasyona sahip kütüphanedir.

Komut Satırı Arayüzü (CLI) ile Esnek Kullanım

Scriptinizi statik değişkenlerle çalıştırmak yerine, kullanıcıdan girdi alan bir CLI aracı haline getirmek, otomasyon süreçlerinizi ciddi oranda hızlandırır. Python'un yerleşik argparse kütüphanesi, bu tür araçlar için endüstri standardıdır.

Aşağıdaki kod bloğu, kullanıcının terminal üzerinden giriş ve çıkış dizinlerini, ayrıca hedef genişliği belirlemesine olanak tanır:

import argparse
from pathlib import Path
from PIL import Image

def resize_images(input_dir, output_dir, width):
    input_path = Path(input_dir)
    output_path = Path(output_dir)
    output_path.mkdir(parents=True, exist_ok=True)

    for file_path in input_path.glob("*"):
        if file_path.suffix.lower() in ['.jpg', '.jpeg', '.png']:
            with Image.open(file_path) as img:
                w_percent = (width / float(img.size[0]))
                h_size = int((float(img.size[1]) * float(w_percent)))
                img = img.resize((width, h_size), Image.Resampling.LANCZOS)
                img.save(output_path / file_path.name)
                print(f"İşlendi: {file_path.name}")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Toplu Resim Boyutlandırıcı")
    parser.add_argument("--input", required=True, help="Kaynak dizin")
    parser.add_argument("--output", required=True, help="Hedef dizin")
    parser.add_argument("--width", type=int, default=800, help="Hedef genişlik")
    
    args = parser.parse_args()
    resize_images(args.input, args.output, args.width)

İleri Seviye Optimizasyon: Çok Çekirdekli İşleme

Pillow tek çekirdek üzerinde çalışır. Eğer binlerce görseliniz varsa, Python'un concurrent.futures modülünü kullanarak CPU çekirdeklerinizi paralel olarak kullanabilir ve işlem süresini %400'e varan oranlarda düşürebilirsiniz.

İşte ProcessPoolExecutor kullanarak paralel işleme örneği:

from concurrent.futures import ProcessPoolExecutor
import os

def process_single_image(file_info):
    # file_info: (dosya_yolu, hedef_dizin, genislik)
    # ... burada yukarıdaki resize mantığı çalışır ...
    pass

def run_parallel(files, output_dir, width):
    with ProcessPoolExecutor() as executor:
        tasks = [(f, output_dir, width) for f in files]
        executor.map(process_single_image, tasks)

Hata Ayıklama ve Loglama Stratejileri

Toplu işlemlerde, hangi görselin neden hata verdiğini bilmek kritiktir. print() fonksiyonu yerine logging modülünü kullanarak hataları bir dosyaya yazmak, uzun süreli işlemlerin takibini kolaylaştırır.

Hata Türü Çözüm Stratejisi
UnidentifiedImageError Dosyanın gerçekten resim olup olmadığını kontrol et (Magic numbers).
OSError (Truncated) ImageFile.LOAD_TRUNCATED_IMAGES = True ayarını kullan.
MemoryError Görseli Image.draft() ile düşük çözünürlükte önizle.
İpucu: Büyük ölçekli projelerde, işlenen görsellerin bir veritabanında (SQLite veya JSON) kaydını tutmak, aynı görsellerin tekrar tekrar işlenmesini engelleyerek sunucu kaynaklarını korur.

Sonuç

Python ile Pillow kullanarak toplu resim boyutlandırma, doğru filtreleme ve hata yönetimi ile oldukça güvenli ve verimli bir süreçtir. Bu rehberde öğrendiğiniz LANCZOS filtreleme, en-boy oranı koruma ve güvenli dosya işleme pratikleri, profesyonel projelerinizde size sağlam bir temel oluşturacaktır.

Bir sonraki adım olarak, bu script'i bir argparse modülü ile birleştirerek komut satırı üzerinden parametre alan (örneğin: python script.py --input ./resimler --size 800) daha esnek bir araç haline getirmeyi deneyebilirsiniz. Başarılar dilerim.

Bu yazıya tepkinizi paylaşın:
Emre Çelik

Eğitici içerik tasarımı ve yapılandırılmış metin oluşturma konusunda deneyimliyim. Kullanıcıların doğrudan sonuca ulaşmasını sağlayan net ve yalın bir anlatım tarzım var.

Yorumlar (0)

Yorum Yaz