Bir görseli 200×200 alana sığdırmakla 200×200 kareye dönüştürmek aynı işlem değil. İlki oranı korur, ikincisi kırpma veya esnetme kararı ister. Arşivimdeki Bitmap tabanlı küçük resim üretimini açıklarken önce bu farkı sabitliyorum; aksi halde teknik olarak doğru boyutta ama yüzleri incelmiş bir önizleme elde etmek kolay.
En dar sınıra göre ölçek seçmek
1200×800 bir fotoğrafı en fazla 200×200 kutuya sığdıralım. Genişlik oranı 200/1200, yükseklik oranı 200/800. Küçük oran seçilince sonuç yaklaşık 200×133 olur. Her iki ekseni bağımsız 200 yapmak fotoğrafı esnetirdi. Örnekte Math.Min(1d, ...) küçük kaynakların büyütülmesini de engelliyor.
using System.Drawing;
using System.Drawing.Drawing2D;
static void Thumbnail(string source, string destination, int maxWidth, int maxHeight)
{
if(maxWidth <= 0 || maxHeight <= 0) throw new ArgumentOutOfRangeException();
using var input = Image.FromFile(source);
var ratio = Math.Min(1d, Math.Min((double)maxWidth/input.Width, (double)maxHeight/input.Height));
var width = Math.Max(1, (int)Math.Round(input.Width*ratio));
var height = Math.Max(1, (int)Math.Round(input.Height*ratio));
using var output = new Bitmap(width,height);
using var graphics = Graphics.FromImage(output);
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.DrawImage(input,0,0,width,height);
output.Save(destination, System.Drawing.Imaging.ImageFormat.Png);
}
maxWidth ve maxHeight sıfırdan büyük olmalı. Hesaplanan boyut yuvarlanırken en az bir piksel korunuyor. Kod yeni Bitmap'e görüntüyü çizip PNG biçiminde yazar. Dolayısıyla hedef dosyanın adı ve gönderilecek MIME türü bu gerçek biçimle uyumlu olmalı; destination sonuna .jpg yazmak üretilen byte'ları JPEG yapmaz.
Bu örneğin platform sınırı
System.Drawing.Common modern .NET uygulamalarında Windows'a özgü bir bağımlılık olarak değerlendirilmelidir. Arşivde çalışan Windows kodunu Linux Docker imajına aynı şekilde taşımayı varsaymam. Linux sunucuda bu iş gerekiyorsa desteklenen başka bir görüntü kütüphanesi seçilir; lisans ve sürüm uyumu o seçimle ayrıca incelenir. Bu örnek, mevcut Bitmap tekniğini anlatıyor; sitenin Linux sunucusunda kullanılacak hazır bir görsel servisi değil.
Çizim kalitesi içeriğe göre değişir
HighQualityBicubic fotoğraf küçültmede değerlendirilebilecek bir seçimdir. Pixel art için ise ara renkler üreterek keskin kareleri yumuşatabilir. Piksel sınırlarını korumak istediğimde en yakın komşu gibi bir ölçekleme ve uygun tamsayı oranlarını değerlendiririm. Tek bir “yüksek kalite” adı bütün görsel türlerinde aynı estetik sonucu vermez.
Orijinal resmin EXIF yönü de boyut kararından önce önemlidir. Bir telefon fotoğrafı metadata ile döndürülmüş olabilir; piksel genişliği/yüksekliğine bakıp yönü uygulamazsam doğru oranla yanlış yönde önizleme üretirim. Renk profili, saydamlık ve çıktı kodlama ayarları da gerçek görüntü seti üzerinde kontrol edilir.
using yalnız temizlik süsü değil
Image, Bitmap ve Graphics yönetilmeyen kaynaklar tutabilir. using bildirimleri bunların kapsam sonunda bırakılmasını sağlar. Image.FromFile kaynak dosyayla ilişkili bir yaşam süresi oluşturduğundan aynı dosyanın üzerine doğrudan yazmak sorun çıkarabilir; ayrı bir hedef veya geçici dosya üzerinden atomik değiştirme seçerim. Bu davranışı yalnız küçük konsol denemesinde değil seri dosya işleme sırasında da sınamak gerekir.
Bir dosya byte olarak küçük olsa bile piksel sayısı çok yüksek olabilir. Kabul edilen dosya boyutu, boyutlar ve toplam piksel alanı için sınır koyarım. Geçersiz görüntü decode hatasını kullanıcıya “dosya işlenemedi” olarak çevirirken sunucuya tam içerik veya özel dosya yolu basmak zorunda değilim.
Önbellek anahtarı dönüşümü de tanımlamalı
Aynı kaynak farklı boyutlarda üretilecekse dosyanın kimliği tek başına yetmez. Kaynak sürümü, hedef kutu, kırpma politikası ve çıktı biçimi önizlemenin kimliğine dahil olabilir. Orijinal değiştiği halde eski thumbnail kalması, başarılı dönüşümden sonra karşılaşılan ayrı bir veri tutarlılığı sorunudur.
Kontrolde yatay 1200×800, dikey 800×1200, küçük 50×30 ve çok dar bir görsel kullanırım. Boyutlar kutuyu aşmamalı, oran korunmalı ve küçük resim büyütülmemeli. Ardından döndürülmüş fotoğraf, saydam PNG ve pixel art ile görsel sonucu incelerim. Sayısal sınırları geçmek, görüntünün doğru görünmesini tek başına kanıtlamaz.
System.Drawing platform sınırı; InterpolationMode seçenekleri.