5.7. Sammansättning av bilder

Ritprimitiverna på föregående sida målar geometriska märken på en bild – en linje, en rektangel, en textbit. Det täcker de flesta annoteringar som en algoritm behöver göra synliga, men inte alla. Ibland är annoteringen i sig själv en bild: en infångad referensbildruta som ska visas sida vid sida med den aktuella, en miniatyrbild av en tidigare infångning visad i ett hörn av förhandsvisningen, eller en tidigare lagrad mall visualiserad ovanpå en live-bildruta för kalibrering. Mekanismen för att rita en bild på en annan är en enda metod – draw_image() – med tillräckligt många parametrar för att hantera positionen, skalningen, färgpaletten och den transparens som verklig sammansättning kräver.

5.7.1. Det grundläggande anropet

I sin enklaste form tar draw_image en annan Image och en position att rita den vid:

reference = image.Image("/sdcard/reference.bmp")
img.draw_image(reference, x=10, y=10)

Destinationen är img; källan är reference; källans pixel längst upp till vänster hamnar vid (10, 10) i img, och resten av källans pixlar följer åt höger och nedåt därifrån. Destinationspixlar som källan täcker skrivs över med källans motsvarande pixlar; pixlar utanför källans avtryck lämnas orörda.

Om källan sträcker sig förbi destinationens kant klipps de delar som faller utanför tyst bort – samma förlåtande beteende som set_pixel uppvisar för positioner utanför intervallet. Applikationskoden behöver inte begränsa positionen till bildens dimensioner i förväg; den kan skicka önskad position och låta metoden sköta klippningen.

5.7.2. Inläsning av en fil direkt

draw_image accepterar en filsökväg i stället för Image-argumentet och läser in filen innan den sätts samman:

img.draw_image("/sdcard/reference.bmp", x=10, y=10)

Det ser ut som en bekvämlighet – en rad i stället för två – och det är det, men skillnaden är mer än syntax. Att konstruera en Image från en fil allokerar en buffert som rymmer de avkodade pixlarna, och den bufferten finns kvar tills skräpsamlingen frigör den. Att skicka sökvägen direkt till draw_image låter modulen avkoda filen till en tillfällig buffert, sätta samman från den och frigöra bufferten när anropet återvänder, utan att applikationskoden behöver hålla en referens till en separat Image mellan bildrutor.

5.7.3. Skalning

När källan och destinationen har olika storlek – en lågupplöst infångning som sätts samman på en högre upplöst arbetsyta, eller en miniatyrbild som behöver storleksanpassas till en viss bråkdel av bildrutan – sköter två skalparametrar storleksändringen av källan medan den ritas:

img.draw_image(reference, x=10, y=10, x_scale=2.0, y_scale=2.0)

x_scale och y_scale är oberoende flyttal; att skicka båda med samma värde skalar likformigt, och att skicka olika värden sträcker ut eller krymper källan längs en axel. Skalningen sker vid rittillfället; källan reference modifieras inte.

En bitmask av hint-flaggor avgör hur skalningen faktiskt interpolerar mellan pixlar. image.BILINEAR ger jämnare resultat på bekostnad av mer beräkning; image.BICUBIC ger ännu jämnare resultat och kostar återigen mer; standardvärdet använder närmaste granne, vilket är billigast och rätt val när källan redan har destinationens pixelupplösning. Flaggor för bildförhållande – SCALE_ASPECT_KEEP, SCALE_ASPECT_EXPAND, SCALE_ASPECT_IGNORE – avgör vad som ska göras när källans bildförhållande inte stämmer överens med rektangeln den ritas in i.

5.7.4. Alfablandning

Som standard ersätter draw_image destinationspixlar med källpixlar. När målet är ett genomskinligt överlägg – så att destinationen syns igenom källan – styr parametern alpha hur de två blandas. alpha=0 visar endast destinationen (ingen källa); alpha=255 är standardvärdet och visar endast källan (fullständig ersättning); mellanliggande värden blandar de två proportionellt:

img.draw_image(overlay, x=0, y=0, alpha=128)

Ett separat alpha_palette-argument är modulens enda mekanism för alfa per pixel. Det tar en GRAYSCALE-bild vars värden används som alfa vid motsvarande position i källan – till exempel en värmekarta vars alfa varierar med dess intensitet. Alfan måste tillhandahållas som det separata gråskaleargumentet; en källbild som bär sin egen alfakanal (säg en PNG med transparens) tar inte med den automatiskt.

5.7.5. Källans ROI och palett

Två ytterligare parametrar kompletterar sammansättningsmekanismen:

  • roi=(x, y, w, h) begränsar källan till en delrektangel av sig själv, så att endast den rektangeln sätts samman på destinationen. Användbart för att beskära inom samma anrop, utan att förbereda ett beskuret mellanled.

  • color_palette ersätter varje källpixels värde via en uppslagstabell innan ritningen – samma mekanism som to_rainbow() och to_ironbow() använder, exponerad här så att ett överlägg kan palettiseras på väg in på destinationen utan en separat konverteringsomgång.

Båda samverkar med allt annat i anropet: skalningen, alfan, mask-argumentet på destinationssidan och roi-parametern på destinationssidan som begränsar skrivningen till en rektangel av destinationen.