C# GÖRÜNTÜ İŞLEME
Görüntü işleme denilince ilk akla gelen dil çoğu zaman Python olur. OpenCV'nin Python bağlaması Stack Overflow'u doldurmuş, NumPy ile birleşince hızlı prototipleme için inanılmaz konforlu. Peki neden bu yazı C# tarafına bakıyor? Çünkü pratikte görüntü işleme yapılan yerin önemli bir bölümü Python script'i değil; bir masaüstü uygulaması, bir Windows servisi veya bir ASP.NET arka ucudur. Kalite kontrol bandının kamera akışını işleyen yazılım, evrak tarayan bir muhasebe modülü, fotoğraf yükleyen e-ticaret panelinin sunucu tarafı — bunların hepsi .NET stack'inde yaşar. Python ile prototip yapıp C# ile production'a almak yerine, baştan C# tarafında kalmak çoğu ekip için daha sürdürülebilir bir yol.
Bu yazı, .NET ekosisteminde görüntü işleme yapmak isteyen geliştiriciler için yazıldı. Kütüphane manzarası, hangi senaryoda hangi aracı seçeceğin, temel işlemlerin kod örnekleri ve cross-platform sorununun nereden geldiği pratik biçimde ele alınıyor.
Kütüphane Manzarası — Tek Bir Doğru Cevap Yok
C# tarafında görüntü işleme yapacaksan üç-dört temel kütüphane vardır ve hepsinin tasarım kararları farklıdır. Birini diğerinin yerine koymak çoğu zaman mümkün değildir; ihtiyacın ne, ona göre seçim yapılır.
- System.Drawing.Common: .NET'in ilk gününden beri var olan, GDI+ üzerine sarmal. Çoğu eski tutorial bunu gösterir. .NET 6 ile birlikte resmi olarak Windows-only ilan edildi — Linux'ta artık desteklenmiyor.
- ImageSharp (SixLabors): Tamamen yönetimli kod, cross-platform, modern API. Filtre, resize, format dönüşümü gibi sunucu tarafı işlerin standart tercihi haline geldi.
- OpenCvSharp / Emgu CV: OpenCV C++ kütüphanesinin .NET bağlamaları. Yüz tanıma, kenar tespiti, kontur analizi gibi computer vision işleri buradan yapılır.
- SkiaSharp: Google'ın Skia rendering motorunun .NET sarmal. Çizim ve UI tarafında güçlü, MAUI içinde varsayılan.
- Magick.NET: ImageMagick'in .NET wrapper'ı. Format desteği ve toplu dönüştürme işlerinde geniş yeteneklere sahip.
Sunucuda thumbnail üreten bir endpoint mi yazıyorsun? ImageSharp. Kameradan gelen akıştan yüz bulacak mısın? OpenCvSharp. Eski WinForms uygulamasını ayakta tutuyor musun? System.Drawing kalmaya devam edebilir. Karar verirken hedef platformu ve işin doğasını birlikte düşünmek gerekir.
System.Drawing Bitti mi?
Tam olarak değil. .NET 6 ile birlikte Microsoft şu kararı aldı: System.Drawing.Common sadece Windows üzerinde desteklenecek. Linux ya da macOS hedefli bir kodda kullanıldığında PlatformNotSupportedException alırsın. Bunun nedeni libgdiplus bağımlılığının Linux tarafında güvenlik ve performans açısından sürdürülebilir olmaması.
Yine de Windows-only bir masaüstü uygulaması yazıyorsan System.Drawing hâlâ pratiktir. Mevcut WinForms kodu binlerce kez bu API'yi kullanır; namespace'in sınıf yapısını ve hangi tiplerin Windows-only olarak işaretlendiğini görmek için resmi API dokümantasyonuna bakmak işini kolaylaştırır. Ama yeni bir proje başlatıyorsan ve uzun vade düşünüyorsan, başta ImageSharp veya SkiaSharp'a yatırım yapmak akıllıca olur.
ImageSharp ile Temel İşlemler
ImageSharp'ın API'si modern ve akıcıdır. Bir görüntüyü yükleyip yeniden boyutlandırıp gri tona çevirmek birkaç satır kodla halledilir:
- Yükleme:
Image.Load(path)veyaImage.Load<Rgba32>(stream)piksel formatını belirleyerek. - Mutate ile dönüşüm:
image.Mutate(x => x.Resize(800, 600).Grayscale());zincirleme operasyon. - Kaydetme:
image.SaveAsJpeg("out.jpg")veyaSaveAsWebp,SaveAsPng.
API'nin önemli özelliği Mutate ile Clone ayrımıdır. Mutate orijinal görüntüyü değiştirir, Clone yeni bir kopya üretir. Asenkron sunucu kodunda aynı görüntüyü paylaşıyorsan Clone tercih edilir; yoksa thread'ler birbirinin verisini bozar.
ImageSharp'ın bir diğer artısı dahili filtre kütüphanesidir: Gaussian blur, brightness, contrast, hue rotation, sepia, vignette gibi sık kullanılan efektler hazır gelir. Kendi kernel'ini tanımlamak istersen ConvolutionProcessor ile özel filtre yazabilirsin.

OpenCvSharp ve Computer Vision
İşin tanıma tarafına geçtiğinde ImageSharp'ın menzili biter. Yüz bulmak, plaka okumak, hareket tespit etmek, kontur çıkarmak — bunlar OpenCV'nin tarihsel olarak uzmanlaştığı alanlardır. C# tarafında OpenCV'ye iki kapı vardır: OpenCvSharp ve Emgu CV. Her ikisi de C++ tarafındaki cv::Mat yapısını .NET'e sarmalar.
OpenCvSharp tarafında klasik bir Canny kenar tespiti örneği şöyle görünür:
- Yükleme:
var src = Cv2.ImRead("input.jpg", ImreadModes.Grayscale); - Yumuşatma:
Cv2.GaussianBlur(src, blurred, new Size(5, 5), 1.5); - Kenar:
Cv2.Canny(blurred, edges, 50, 150); - Kaydet:
Cv2.ImWrite("edges.jpg", edges);
Python OpenCV ile gözle görülür benzerlik vardır. Bu kasıtlıdır; OpenCvSharp dökümantasyonunda Python örneklerini doğrudan C#'a aktarmak kolaydır. Tek dikkat edilmesi gereken kaynak yönetimi — Mat nesneleri unmanaged bellek tutar, using bloğu içinde tutmak veya Dispose çağırmak şarttır. Yoksa GC fark etmediği için bellek hızla şişer.
Daha derin bir C# pratiği geliştirmek isteyenler için yapılandırılmış C# eğitimi hem dil temellerini hem nesne tabanlı tasarım örüntülerini sırayla işler; bu temel olmadan görüntü işleme kodu zamanla bakımı zor bir hâle gelir.
Performans ve Bellek Yönetimi
Görüntü işleme bellek-yoğun bir iştir. 4K çözünürlükte bir RGB görüntü yaklaşık 24 MB yer kaplar; bunu birkaç kez kopyalayan kod kısa sürede gigabaytlara çıkar. .NET tarafında dikkat edilecek noktalar:
- Stream üzerinden yükle: Tüm dosyayı belleğe almadan,
FileStreamile akıtarak işlemek büyük dosyalarda yarar sağlar. - Pixel format seçimi: Renk bilgisine ihtiyacın yoksa Grayscale, alpha gereksizse Rgb24 — bellek yarıya iner.
- Span<T> ve Memory<T>: ImageSharp'ın
ProcessPixelRowsAPI'si doğrudan piksel buffer'ına Span üzerinden erişim verir; LINQ veya kopya gerektirmez. - Toplu işlerde paralelleştirme:
Parallel.ForEachile binlerce thumbnail üretmek tek thread'e göre 5-8 kat hızlanabilir; ama her thread'in kendi Image kopyası olmalı.
OpenCvSharp tarafında ek olarak GPU desteği vardır. CUDA destekli bir NVIDIA kartında cv::cuda::GpuMat ile filtre uygulamak büyük görüntülerde CPU'nun 10-20 katı performans verebilir. Tarama bandı veya canlı video gibi senaryoda fark belirleyicidir.
Tipik Senaryolar ve Hangi Kütüphane
Karar matrisini somutlaştırırsak şöyle bir tablo çıkar:
- E-ticaret thumbnail servisi: ImageSharp. Cross-platform, modern API, format dönüşümü güçlü.
- OCR / evrak okuma: Tesseract.NET + ImageSharp ön işleme + (gerekirse) OpenCvSharp ile düzeltme.
- Kalite kontrol kamerası: OpenCvSharp. Real-time akış, kontur tespiti, ölçüm.
- Çizim tabanlı uygulama (Paint benzeri): SkiaSharp. Vektör + raster karışık çizim için optimize.
- Eski WinForms bakım: System.Drawing kalmaya devam.
- Toplu format dönüştürme (PDF, TIFF, RAW): Magick.NET. Format desteği en geniş.
Pratikte projeler tek kütüphaneye bağlı kalmaz. ImageSharp ile yükle, OpenCvSharp ile kenar çıkar, sonuca göre Magick.NET ile PDF'e yaz — böyle melez akışlar gayet sağlıklıdır. Önemli olan her birinin ne için var olduğunu net bilmek.
Cross-Platform Konuşulduğunda
Linux sunucuda Docker içinde .NET 8 uygulaması koşuyorsan System.Drawing seçenek değildir. Aynı şekilde Azure App Service'in Linux planında, AWS Lambda'da, container tabanlı her ortamda ImageSharp veya SkiaSharp tercih edilir. OpenCvSharp da Linux'ta çalışır ama native bağımlılığını (libopencv) Docker imajına manuel kurman gerekir — opencvsharp/opencvsharp:ubuntu hazır imajları bu işi kolaylaştırır.
macOS tarafı .NET MAUI ile birlikte daha yaygın hale geldi. ImageSharp ve SkiaSharp burada da sorunsuz çalışır. Apple Silicon (ARM64) üzerinde OpenCvSharp'ın ARM derlemesinin olduğunu doğrulamak gerekir; x64-only paket çekersen runtime'da hata alırsın.
Hangisinden Başlamalı?
Henüz seçim yapmadıysan ve sıfırdan başlıyorsan ImageSharp ile başlamak en güvenli yoldur. API modern, dokümantasyon iyi, NuGet'ten SixLabors.ImageSharp paketini çekip 10 satır kod ile ilk dönüşümünü yapabilirsin. Gerçek anlamda computer vision'a — yüz tanıma, hareket tespiti, AR — geçeceksen OpenCvSharp ile devam edersin.
Görüntü işleme öğrenirken Python tutorial'larından uzak durmana gerek yok; kavramlar (kernel, convolution, histogram, threshold) dilden bağımsızdır. Python'da gördüğün bir filtreyi C#'a aktarmak çoğu zaman birebir karşılıklıdır. Python topluluğu daha kalabalık olduğu için örnek bulmak daha kolay, ama production kodu için C# stack'i sürdürülebilirlik açısından önde gider.



