Ana içeriğe geç
Ahmet Faruk UzunkayaYaratıcı geliştirici
← Projelere dön
MasaüstüTamamlandıGüncellendi · 7 Ekim 2026

Glance

Windows'un açamadığı HEIC, RAW ve PSD dosyalarını ek codec kurmadan açan bir görüntüleyici.

Windows 10 ve 11 için yazdığım hızlı, ücretsiz ve açık kaynak bir görüntüleyici. HEIC, AVIF, JPEG XL, kamera RAW, PSD ve HDR/EXR dosyalarını Microsoft Store'dan codec eklentisi kurmadan açıyor. Görselleri arka planda ekran boyutunda çözüp GPU'da çiziyor, gezindiğin yöndeki 16 fotoğrafı da önceden hazırlıyor.

C#.NET 10WinUI 3Win2DNativeAOT
Glance ekran görüntüsü
Durum
Tamamlandı
Kategori
Masaüstü
Güncelleme
7 Ekim 2026
Yığın
C#.NET 10WinUI 3Win2DNativeAOT
Glance

Glance, Windows 10 ve 11 için yazdığım bir görüntü görüntüleyici. HEIC, AVIF, JPEG XL, kamera RAW, PSD ve HDR/EXR dosyalarını açmak için Microsoft Store'dan codec eklentisi kurman gerekmiyor; .NET çalışma zamanı da bütün decoder'lar da paketin içinde geliyor. Desteklediği formatlar günlük JPEG ve PNG'den başlayıp JPEG XR, JPEG 2000 ve QOI'ye, CR2, CR3, NEF, ARW, DNG, RAF gibi kamera RAW'larından PSD/PSB, TGA, EXR, Radiance HDR, SVG ve DDS'ye kadar uzanıyor. HEIC patentli bir format, o yüzden bu dosyaları yalnızca okuyorum, hiç yazmıyorum.

Bir fotoğrafı açtığında klasördeki diğerleri, Dosya Gezgini'ndeki doğal ad sırasıyla bir film şeridine diziliyor. Yakınlaştırma imlecin olduğu noktanın etrafında oluyor, kaydırma da momentumlu. Bilgi panelinde canlı bir RGB histogramı, makine ve lens, pozlama, çekim tarihi ve GPS konumu var. İki fotoğrafı yan yana koyup birlikte yakınlaştırarak karşılaştırabilir, 8× büyüteçle bir pikselin rengini #RRGGBB olarak kopyalayabilirsin. Slayt gösterisi de Ken Burns hareketiyle oynuyor.

Düzenleme tarafında kayıpsız JPEG döndürme, kırpma ve farklı formatlarda kaydetme var. Dosyaların için de iki güvence koydum: yerinde kaydederken orijinal önce Geri Dönüşüm Kutusu'na taşınıyor, sildiğin bir dosyayı da 5 saniye içinde geri alabiliyorsun. Gömülü ICC profilleri sRGB'ye dönüştürüldüğü için iPhone'un Display P3 fotoğrafları doğru renklerle görünüyor. Arayüz Türkçe ve İngilizce.

Dosyayı açmadan önce

Her dosya DecoderRouter üzerinden geçiyor. Router dosyanın ilk 64 baytını okuyor, decoder'ları önceliğe göre sıralıyor ve önce magic byte'lara, sonra uzantıya bakarak uygun olanı seçiyor. Sıralama şöyle: önce Windows'un yerleşik formatları için WIC, sonra RAW önizleme tarayıcısı, en son da HEIC, AVIF, JXL, PSD ve EXR gibi formatlar için Magick.NET. Bir decoder hata verirse sıradaki deneniyor; hiçbiri başaramazsa bütün hatalar tek bir InvalidDataException içinde toplanıyor.

WIC'e WinRT üzerinden değil, COM üzerinden gidiyorum. Sebebi şu: WinRT BitmapDecoder yolu renk yönetimini yalnızca JPEG için yapıyordu. COM hattı ise her formatta karenin ICC renk bağlamını okuyup IWICColorTransform çalıştırıyor. Hat sırasıyla kare, ölçekleyici, çevirme / döndürme, renk dönüşümü ve PBGRA adımlarından geçiyor; interop kodu derleme sırasında Microsoft.Windows.CsWin32 ile üretiliyor. Magick.NET'i ise tembel yüklüyorum: CanDecode kontrolünü Glance'in kendi magic byte tablosu yapıyor, Magick çağrıları da NoInlining metotlarda duruyor. Bu yüzden Magick.NET.Core, Magick'e gerçekten ihtiyaç duyan ilk dosya açılana kadar belleğe girmiyor.

RAW dosyaları için kendi önizleme tarayıcımı yazdım. RawPreviewDecoder, formattan bağımsız olarak dosyanın içine gömülü en büyük kayıplı (SOF0-2) JPEG'i bulup WIC ile çözüyor, yönü de TIFF IFD0'dan alıyor. Tam LibRaw demosaic yalnızca önizlemenin ötesine yakınlaştığında çalışıyor. Aradaki farkı ADR 0005'teki ölçüm gösteriyor: bir Canon S90 CR2 dosyası bu yolla 100 ms'de, tam demosaic ile 7,6 saniyede açılıyor.

Bir sonraki fotoğraf zaten hazır

Görüntüleri pencerenin boyutunda değil, monitörün fiziksel piksel sayısında çözüyorum. Böylece pencereyi büyüttüğünde ya da tam ekrana geçtiğinde yeniden çözmek gerekmiyor. Çözülen BGRA veri Win2D CanvasBitmap olarak GPU'ya yükleniyor, CPU tarafındaki piksel dizisi de bırakılıyor. Bitmap'ler bir LRU önbellekte duruyor; önbelleğin bayt bütçesi, RAM'in %10'u ile 1 GB'tan hangisi küçükse o kadar. Çözme ve GPU'ya yükleme arayüz iş parçacığının dışında yapılıyor. Önbelleğe ekleme ise arayüz iş parçacığında olduğu için bir bitmap çizim sırasında önbellekten atılamıyor.

Bir görüntü gösterildikten sonra Prefetch.Order komşuları önem sırasına göre kuyruğa alıyor. Son gezinme yönü d ise sıra şöyle:

d, -d, 2d, -2d, 3d, 4d, ..., 16d

Önce bir sonraki görüntü ile az önce bıraktığın görüntü hazırlanıyor, çünkü bir adım geri dönmek sık oluyor. Sonra iki yönde de ikinci adım geliyor, ardından ileri doğru 16 görüntüye kadar uzanan bir dizi. Klasör yeni açıldıysa yön ileri kabul ediliyor. Film şeridindeki küçük nokta, GPU'da hazır bekleyen, yani anında açılacak görüntüleri işaretliyor. Bu düzeni ayrı bir yazıda koddan alıntılarla anlattım.

Explorer'daki boş simgeler

Windows kendi küçük resim işleyicilerini yalnızca JPEG, PNG, GIF, BMP, TIFF ve ICO için getiriyor. HEIC, AVIF ve WebP için Store'dan codec eklentisi istiyor, JXL, RAW, PSD ve EXR içinse hiçbir şey göstermiyor. Bu boşluğu Glance.Thumbnails dolduruyor: IThumbnailProvider, IInitializeWithStream ve IClassFactory arayüzlerini uygulayan, NativeAOT ile NativeLib=Shared olarak derlenen 4,1 MB'lık bir DLL. Explorer'ın sürecine CLR yüklenmediği için diğer shell eklentileriyle çalışma zamanı sürümü çakışması yaşanmıyor.

COM katmanını, AOT ile uyumlu olsun diye kaynak üretimli ComWrappers ile yazdım. IStream doğrudan vtable üzerinden okunuyor ve yalnızca Read ile Stat kullanılıyor. İşleyici aynı MagickDecoder'ı ve RAW önizleme tarayıcısını kullanıyor; WIC formatlarını ise Windows'un kendi işleyicilerine bırakıyor. Kaydı HKCU altında, yönetici izni istemeden yapıyorum ve başka bir uygulamanın işleyicisi kayıtlı olan uzantılara dokunmuyorum.

Dört proje, altı karar kaydı

Çözümü dört projeye ayırdım:

  • Glance.App: WinUI 3 arayüzü, Win2D tuvali ve sistem kaydı.
  • Glance.Core: arayüzden bağımsız kısım; klasör gezinme, dosya izleme, önbellek, ön yükleme sırası ve ayarlar.
  • Glance.Imaging: decoder'lar, metadata ve düzenleme.
  • Glance.Thumbnails: küçük resim işleyicisi.

Dil C# ve .NET 10; yanında CommunityToolkit.Mvvm ve MetadataExtractor kullanıyorum.

Önemli kararları docs/adr altında altı kayıt olarak yazdım. İlki, Windows App SDK meta paketi yerine yalnızca WinUI ve InteractiveExperiences bileşen paketlerini almayı ve soğuk açılış bütçesine sığmak için DI'ı Generic Host olmadan kurmayı anlatıyor. Diğerlerinde WinRT yolunun DCT ölçeklemesi kullanmadığı tespiti, Magick.NET'in tembel yükleme kuralları, RAW decoder seçimi ve yukarıda anlattığım COM ve NativeAOT kararları var.

x64 ve ARM64 sürümleri GitHub Actions ile derlenip son sürüm sayfasına konuyor. Kurulum dosyası henüz kod imzalı olmadığı için SmartScreen ilk açılışta sana bir uyarı gösterebilir.