5.21. Skaalaus, peilaus ja rajaus

Edelliset aliosiot käsittelivät kaikki pikseleitä samoissa kohdissa, joista ne alkoivat. Muunnos-perhe muuttaa tämän. Skaalaus lähettää jokaisen syötepikselin eri ulostulokohtaan, mahdollisesti useaan ulostulokohtaan kerralla (suurennettaessa) tai kohtaan, joka jaetaan useiden muiden syötepikselien kanssa (pienennettäessä). Peilaus ja kierto tekevät saman asian eri kuvauksen kautta. Rajaus säilyttää syötepikselien suorakulmaisen osajoukon ja hylkää loput.

image-moduuli tarjoaa tämän perheen kolmen menetelmän kautta, jotka jakavat suurimman osan argumenteistaan ja toiminnastaan:

  • copy() – tuottaa kopion kuvasta, mahdollisesti skaalattuna, rajattuna tai uudelleensuunnattuna.

  • crop() – sama toiminto kuin copy, mutta odotuksena, että sovellus poimii osasuorakulmion lähteestä.

  • scale() – jälleen sama, odotuksena, että sovellus muuttaa tuloksen kokoa.

Nämä kolme jakavat samat argumentit ja saman muunnoskoneiston; ero on siinä, mihin tulos oletusarvoisesti päätyy. copy() tuottaa uuden kuvan, kun taas crop() ja scale() muokkaavat lähdettä paikallaan.

5.21.1. Jaetut argumentit

Yksittäinen kutsu yhdistää minkä tahansa skaalauksen, rajauksen, suuntauksen ja kanavanpoiminnan yhdistelmän, jota sovellus pyytää:

x_scale ja y_scale skaalaavat syötettä vaaka- ja pystyakselilla toisistaan riippumatta. Molempien oletusarvo on 1.0 (ei skaalausta). Eri arvot kummallekin tuottavat epätasaisen skaalauksen – esimerkiksi kehys, joka on venytetty kaksi kertaa niin leveäksi kuin se on korkea.

roi rajoittaa syötteen lähdekuvan suorakulmioon ottaen vain ne pikselit mukaan loppuun muunnokseen. Tämä on toiminnon ”rajaus”-osa: anna roi poimiaksesi osa-alueen.

hint on lippubittikenttä, joka valitsee interpolointimenetelmän ja mahdolliset suuntauspeilaukset. Useat liput yhdistyvät bittikohtaisella TAI-operaatiolla (hint=image.BILINEAR | image.HMIRROR). Liput jakautuvat kahteen ryhmään – interpolointi-perheeseen ja suuntaus-perheeseen – joilla ei ole mitään tekemistä toistensa kanssa mutta jotka jakavat saman bittikentän.

rgb_channel valitsee yksittäisen kanavan RGB565-lähteestä. 0 tarkoittaa punaista, 1 vihreää, 2 sinistä; tulos tulee ulos harmaasävykuvana, joka sisältää vain kyseisen kanavan. Hyödyllistä esimerkiksi pelkän punaisen kanavan kynnystämiseen.

color_palette ja alpha_palette kuvaavat pikseliarvot uudelleen hakutaulukon kautta ulostuloreitillä, samalla tavalla kuin muunnosmenetelmät to_rainbow() ja to_ironbow() tekevät.

copy=True ja copy_to_fb=True noudattavat samaa käytäntöä, jota jokainen muu tuloksen tuottava menetelmä käyttää – paikallaan oletusarvoisesti, copy=True varaa erillisen tuloksen, copy_to_fb=True sijoittaa tuloksen kehyspuskuriin IDE:n esikatselua varten.

5.21.2. Interpolointi: AREA, BILINEAR, BICUBIC

Kun skaalaus lähettää jokaisen ulostulopikselin kohtaan, joka ei ole linjassa minkään yksittäisen syötepikselin kanssa, menetelmän on valittava, mikä arvo kirjoitetaan. Kolme lippua ohjaavat sitä, miten:

image.BILINEAR interpoloi neljän lähimmän syötepikselin välillä painottaen niitä niiden etäisyydellä ulostulokohdasta. Tulos on tasaisempi kuin lähinaapuri, eikä viistoissa viivoissa näy nyrjähdyksiä, mutta ylimääräinen laskenta maksaa noin nelinkertaisesti lähinaapuriläpikäyntiin verrattuna. Oikea valinta useimpaan suurennustyöhön ja kaikkiin ei-kokonaislukuisiin skaalauskertoimiin.

image.BICUBIC interpoloi kuudentoista lähimmän syötepikselin välillä kuutiokäyrää käyttäen, mikä tuottaa vielä tasaisempia tuloksia jälleen suuremman laskennan kustannuksella. Paras laatu sitä tarvitseville kustannusherkille sovelluksille; harvoin ylimääräisen laskennan arvoinen reaaliaikaisille kehyksille, jotka IDE vain näyttää.

image.AREA keskiarvoistaa jokaisen syötepikselin, joka osuu ulostulopikselin jalanjäljen sisään – oikea algoritmi pienentämiseen. Bilineaarinen ja bikuubinen ovat interpoloijia: ne arvioivat arvon lähdepikselien välillä, mikä on juuri se, mitä suurennus tarvitsee, mutta pienennettäessä jokainen ulostulopikseli kattaa monta lähdepikseliä, ja interpoloija lukee vain muutaman lähimmän niistä – ohitettu yksityiskohta palaa laskostumisena. image.AREA taittaa sen sijaan jokaisen katetun pikselin keskiarvoon.

Oletusskaalausalgoritmi ilman vihjettä on lähinaapuri, joka on halvin ja oikea vastaus silloin, kun lähde on jo kohteen pikseliresoluutiolla.

5.21.3. Suuntaus: peilaukset ja kierrot

Suuntauksen liput ovat pieni joukko totuusarvomuunnoksia, jotka yhdistyvät vapaasti keskenään ja interpolointilippujen kanssa:

  • image.VFLIP kääntää kuvan pystysuunnassa (yläosasta tulee alaosa).

  • image.HMIRROR peilaa sen vaakasuunnassa (vasemmasta tulee oikea).

  • image.TRANSPOSE vaihtaa x- ja y-akselit (riveistä tulee sarakkeita).

Useimmat kierrot syntyvät yhdistämällä nämä kolme. Moduuli tarjoaa myös nimettyjä pikavalintoja:

  • image.ROTATE_90 (= VFLIP | TRANSPOSE)

  • image.ROTATE_180 (= HMIRROR | VFLIP)

  • image.ROTATE_270 (= HMIRROR | TRANSPOSE)

Koodissa:

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

5.21.4. Kuvasuhteen käsittely

Kun lähteen kuvasuhde ei vastaa suorakulmiota, johon se piirretään, kolme lippua päättää, mitä epäsuhdalle tehdään:

image.SCALE_ASPECT_KEEP säilyttää lähteen kuvasuhteen ja kirjekuorittaa tuloksen – lähde skaalataan, kunnes se mahtuu kohteen sisään, ja tyhjät (nolla-) pikselit täyttävät loput kohteesta. Oikea valinta silloin, kun lähteen pitäminen vääristymättömänä on tärkeämpää kuin koko ulostulon täyttäminen.

image.SCALE_ASPECT_EXPAND säilyttää lähteen kuvasuhteen ja rajaa sen – lähde skaalataan, kunnes se täyttää kohteen, ja kohteen yli ulottuvat osat leikataan pois. Oikea valinta silloin, kun koko ulostulon täyttäminen on tärkeämpää kuin lähteen jokaisen osan näkeminen.

image.SCALE_ASPECT_IGNORE jättää kuvasuhteen huomiotta ja venyttää lähteen täyttämään kohteen hyväksyen sen aiheuttaman vääristymän. Oikea valinta silloin, kun sovellus on jo ottanut vääristymän huomioon – esimerkiksi silloin, kun kohteen mitat eivät tosiasiassa ole saman näkymän suorakulmio.

Oletus (ei kuvasuhdelippua asetettuna) on sama kuin SCALE_ASPECT_IGNORE: venytä täyttämään. Sovellukset, jotka välittävät kuvasuhteesta, määrittävät yhden kolmesta nimenomaisesti.

5.21.5. Milloin kumpaakin kannattaa käyttää

Useimmat koonmuutokset käyttävät scale()-menetelmää yhdessä x_scale / y_scale -parin ja interpolointivihjeen kanssa:

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

Useimmat kierrot käyttävät samaa kutsua vihjeellä hint=image.ROTATE_90 tai vastaavalla.

Rajaus käyttää crop()-menetelmää oletusarvosta poikkeavalla roi-arvolla:

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

Kun lähteen on selvittävä toiminnosta ehjänä – vertailukehyksen kaappaaminen, pienoiskuvan ottaminen kehyksestä, joka aiotaan käsitellä tuhoavasti – copy() tuottaa tuloksen uutena kuvana ja jättää lähteen koskemattomaksi:

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

Tuo oletus on todellinen ero kolmen nimen takana: scale ja crop muuntavat paikallaan, copy varaa muistia. Tuloksen sijoitusavainsanat kuromat eron umpeen: copy=True-arvo scale- tai crop-menetelmässä varaa tuloksen erilliseen kekopuskuriin lähteen ylikirjoittamisen sijaan, ja copy_to_fb=True-arvo missä tahansa kolmesta sijoittaa sen kehyspuskuriin IDE:n esikatselua varten.