5.21. Ölçekleme, çevirme ve kırpma

Önceki alt bölümlerin hepsi, piksellerin başladıkları konumlardaki hâlleri üzerinde çalıştı. Dönüşüm ailesi bunu değiştirir. Ölçekleme, her giriş pikselini farklı bir çıkış konumuna gönderir; muhtemelen aynı anda birkaç çıkış konumuna (yukarı ölçeklerken) ya da birkaç başka giriş pikseliyle paylaşılan bir konuma (aşağı ölçeklerken). Çevirme ve döndürme, farklı bir eşleme aracılığıyla aynı şeyi yapar. Kırpma, giriş piksellerinin dikdörtgen bir alt kümesini tutar ve gerisini atar.

image modülü bu aileyi, argümanlarının çoğunu ve davranışlarının çoğunu paylaşan üç yöntem aracılığıyla sunar:

  • copy() – görüntünün, muhtemelen ölçeklenmiş, kırpılmış ya da yeniden yönlendirilmiş bir kopyasını üretir.

  • crop()copy ile aynı işlem, ancak uygulamanın kaynaktan bir alt dikdörtgen seçeceği beklentisiyle.

  • scale() – yine aynısı, ancak uygulamanın sonucu yeniden boyutlandıracağı beklentisiyle.

Üçü de aynı argümanları ve aynı dönüşüm mekanizmasını paylaşır; fark, sonucun varsayılan olarak nereye düştüğüdür. copy() yeni bir görüntü üretirken, crop() ve scale() kaynağı yerinde değiştirir.

5.21.1. Paylaşılan argümanlar

Tek bir çağrı, uygulamanın istediği ölçekleme, kırpma, yönlendirme ve kanal çıkarma kombinasyonlarının her birini birleştirir:

x_scale ve y_scale, girişi yatay ve dikey eksenler boyunca bağımsız olarak ölçekler. Her ikisi de varsayılan olarak 1.0 (ölçekleme yok) değerindedir. Her biri için farklı değerler, tekdüze olmayan bir ölçekleme üretir – örneğin yüksekliğinin iki katı genişliğe uzatılmış bir çerçeve.

roi, girişi kaynak görüntünün bir dikdörtgeniyle sınırlar ve dönüşümün geri kalanına yalnızca o pikselleri alır. Bu, işlemin “kırpma” kısmıdır: bir alt bölge çıkarmak için bir roi geçirin.

hint, enterpolasyon yöntemini ve varsa yönlendirme çevirmelerini seçen bir bayrak bit alanıdır. Birden çok bayrak bit düzeyinde OR ile birleşir (hint=image.BILINEAR | image.HMIRROR). Bayraklar iki gruba ayrılır – enterpolasyon ailesi ve yönlendirme ailesi – bunların birbiriyle hiçbir ilgisi yoktur ama aynı bit alanını paylaşırlar.

rgb_channel, bir RGB565 kaynağının tek bir kanalını seçer. 0 kırmızı, 1 yeşil, 2 mavi anlamına gelir; sonuç, yalnızca o kanalı içeren bir gri tonlama görüntüsü olarak çıkar. Örneğin yalnızca kırmızı kanal üzerinde eşikleme yapmak için kullanışlıdır.

color_palette ve alpha_palette, çıkış yolunda piksel değerlerini bir arama tablosu aracılığıyla yeniden eşler; tıpkı to_rainbow() ve to_ironbow() dönüştürme yöntemlerinin yaptığı gibi.

copy=True ve copy_to_fb=True, sonuç üreten her diğer yöntemin kullandığı aynı kuralı izler – varsayılan olarak yerinde, copy=True ayrı bir sonuç ayırır, copy_to_fb=True ise sonucu IDE önizlemesi için çerçeve arabelleğine (frame buffer) yerleştirir.

5.21.2. Enterpolasyon: AREA, BILINEAR, BICUBIC

Ölçekleme, her çıkış pikselini herhangi bir tek giriş pikseliyle hizalanmayan bir konuma gönderdiğinde, yöntem hangi değeri yazacağını seçmek zorundadır. Üç bayrak bunun nasıl olacağını denetler:

image.BILINEAR, çıkış konumuna olan uzaklıklarına göre ağırlıklandırılmış en yakın dört giriş pikseli arasında enterpolasyon yapar. Sonuç, en yakın komşudan daha pürüzsüzdür ve çapraz çizgilerde görünür tırtıklanma olmaz, ancak ek aritmetik, en yakın komşu geçişinin yaklaşık dört katına mal olur. Çoğu yukarı ölçekleme işi ve herhangi bir tam sayı olmayan ölçek faktörü için doğru seçim.

image.BICUBIC, kübik bir eğri kullanarak en yakın on altı giriş pikseli arasında enterpolasyon yapar; bu da daha fazla aritmetik karşılığında daha da pürüzsüz sonuçlar üretir. Buna ihtiyaç duyan, maliyete duyarlı uygulamalar için en iyi kalite; IDE’nin yalnızca görüntüleyeceği canlı çerçeveler için ek hesaplamaya nadiren değer.

image.AREA, çıkış pikselinin kapsamı içine düşen her giriş pikselinin ortalamasını alır – aşağı ölçekleme için doğru algoritma. Bilinear ve bicubic enterpolatördür: kaynak pikseller arasında bir değer tahmin ederler ki bu yukarı ölçeklemenin ihtiyacı olan şeydir, ancak aşağı ölçeklerken her çıkış pikseli birçok kaynak pikseli kapsar ve bir enterpolatör yalnızca en yakın birkaçını okur – atladığı ayrıntı, takma ad (aliasing) olarak geri döner. image.AREA ise bunun yerine kapsanan her pikseli ortalamaya katar.

Herhangi bir ipucu olmadan varsayılan ölçekleme algoritması en yakın komşudur; bu da en ucuz olanıdır ve kaynak zaten hedefin piksel çözünürlüğündeyse doğru cevaptır.

5.21.3. Yönlendirme: çevirmeler ve döndürmeler

Yönlendirme bayrakları, hem birbiriyle hem de enterpolasyon bayraklarıyla serbestçe birleşen küçük bir mantıksal dönüşümler kümesidir:

  • image.VFLIP, görüntüyü dikey olarak çevirir (üst, alt olur).

  • image.HMIRROR, görüntüyü yatay olarak yansıtır (sol, sağ olur).

  • image.TRANSPOSE, x ve y eksenlerini değiştirir (satırlar sütun olur).

Çoğu döndürme, bu üçünün birleştirilmesinden gelir. Modül ayrıca adlandırılmış kısayollar da sunar:

  • image.ROTATE_90 (= VFLIP | TRANSPOSE)

  • image.ROTATE_180 (= HMIRROR | VFLIP)

  • image.ROTATE_270 (= HMIRROR | TRANSPOSE)

Kodda:

img.copy(hint=image.ROTATE_90, copy_to_fb=True)

5.21.4. En-boy işleme

Kaynağın en-boy oranı, çizildiği dikdörtgenle eşleşmediğinde, üç bayrak bu uyumsuzlukla ne yapılacağına karar verir:

image.SCALE_ASPECT_KEEP, kaynağın en-boy oranını korur ve sonucu letterbox eder – kaynak, hedefin içine sığana kadar ölçeklenir ve hedefin geri kalanı boş (sıfır) piksellerle doldurulur. Kaynağı bozulmadan tutmak, tüm çıktıyı doldurmaktan daha önemli olduğunda doğru seçim.

image.SCALE_ASPECT_EXPAND, kaynağın en-boy oranını korur ve onu kırpar – kaynak, hedefi dolduracak kadar ölçeklenir ve hedefin ötesine taşan kısımlar kesilir. Tüm çıktıyı doldurmak, kaynağın her parçasını görmekten daha önemli olduğunda doğru seçim.

image.SCALE_ASPECT_IGNORE, en-boy oranını yok sayar ve kaynağı hedefi dolduracak şekilde uzatır, bunun getirdiği bozulma ne olursa olsun kabul eder. Uygulama bozulmayı zaten hesaba katmışsa – örneğin hedefin boyutları aslında aynı sahnenin bir dikdörtgeni değilse – doğru seçim.

Varsayılan (hiçbir en-boy bayrağı ayarlanmamış), SCALE_ASPECT_IGNORE ile aynıdır: doldurmak için uzat. En-boy oranını önemseyen uygulamalar, üç bayraktan birini açıkça belirtir.

5.21.5. Hangisine ne zaman başvurmalı

Çoğu yeniden boyutlandırma, bir x_scale / y_scale çifti ve bir enterpolasyon ipucuyla scale() kullanır:

img.scale(x_scale=0.5, y_scale=0.5, hint=image.AREA)

Çoğu döndürme, aynı çağrıyı hint=image.ROTATE_90 veya benzeriyle kullanır.

Kırpma, varsayılan olmayan bir roi ile crop() kullanır:

img.crop(roi=(40, 30, 200, 150))

Kaynağın işlemden sağ çıkması gerektiğinde – bir referans çerçevesi yakalarken, yıkıcı bir şekilde işlenmek üzere olan bir çerçevenin küçük resmini alırken – copy() sonucu yeni bir görüntü olarak üretir ve kaynağa dokunmadan bırakır:

thumbnail = img.copy(x_scale=0.25, y_scale=0.25, hint=image.AREA)

Bu varsayılan, üç ismin arkasındaki asıl farktır: scale ve crop yerinde dönüştürür, copy ise ayırır. Sonuç yerleştirme anahtar sözcükleri aradaki açığı kapatır: scale veya crop üzerindeki copy=True, sonucu kaynağın üzerine yazmak yerine ayrı bir yığın arabelleği olarak ayırır ve üçünden herhangi biri üzerindeki copy_to_fb=True, onu IDE önizlemesi için çerçeve arabelleğine (frame buffer) yerleştirir.