Grafikk
Grunnleggende tegnefunksjoner
Flere muligheter
Eksempler
Kom i gang
I dette kurset benytter vi et bibliotek for å lage grafikk som heter uib-inf100-graphics. Dette biblioteket er en forenklet utgave av et standard grafikk-rammeverk i Python som heter tkinter.
- Selv om vi har gjort noen forenklinger for å komme rask i gang, gir rammeverket frihet til å være kreativ og lage et rikt utvalg av grafiske applikasjoner.
- Alt vi lærer vil være direkte anvendbart i tkinter hvis du bestemmer deg for å oppgradere til et større rammeverk senere.
I dette kurset benytter vi versjon 0.4.0 av uib-inf100-graphics.
Før du kan installere uib-inf100-graphics, må du
- Ha installert Python 3.10 eller nyere, og
- Ha installert tkinter.
Tkinter følger automatisk med dersom du installerte Python med hjelp av installeren fra python.org, men fulgte ikke med hvis du installerte Python med hjelp av en pakkebehandler som f.eks. apt
eller brew
. Hvis du ikke har tkinter, må du installere det før du kan installere uib-inf100-graphics.
Den letteste måten å installere uib-inf100-graphics er å kopiere skripet under inn i en tom Python-fil og så kjøre den. Svar yes
når du blir spurt om du vil installere pakken.
import sys
from subprocess import run
package_name = "uib-inf100-graphics"
# Sjekk at Python-versjonen er 3.10 eller nyere
if ((sys.version_info[0] != 3) or (sys.version_info[1] < 10)):
raise Exception(f"{package_name} requires Python 3.10 or later. "
+ "Your current version is: "
+ f"{sys.version_info[0]}.{sys.version_info[1]}")
# Spør brukeren om å installere pakken
ans = input(f"\n\nType 'yes' to install {package_name}: ")
if ((ans.lower() == "yes") or (ans.lower() == "y")):
print()
# Oppdater pip
cmd_pip_update = f"{sys.executable} -m pip install --upgrade pip"
print(f"Attempting to update pip with command: {cmd_pip_update}")
run(cmd_pip_update.split())
print()
# Installer pakken
cmd_install = f"{sys.executable} -m pip install {package_name}"
print(f"Attempting to install {package_name} with command: {cmd_install}")
run(cmd_install.split())
else:
print(f"Did not attempt to install {package_name} now")
print("\n")
Åpne terminalen (Windows: PowerShell). Skriv inn følgende kommando for å oppdatere pip:
python -m pip install --upgrade pip
Skriv deretter denne kommandoen for å installere uib-inf100-graphics:
python -m pip install uib-inf100-graphics
Dersom du får en feilmelding om at python-kommandoen ikke finnes, prøv å erstatte python
med python3
, python3.11
eller py
i stedet.
For å sjekke at installasjonene var vellykket, opprett en ny Python-fil og skriv inn følgende:
from uib_inf100_graphics.simple import canvas, display
canvas.create_rectangle(100, 50, 300, 150, outline="red")
canvas.create_text(200, 100, text="Hei, grafikk!", font="Arial 20 bold")
display(canvas)
Når du kjører filen skal du se et vindu som ser omtrent slik ut:
Koordinatsystemet
Ulikt det vi er vant til fra matematikken på skolen, vokser y-aksen nedover istedet for oppover. Dermed er \((0, 0)\) punktet til venstre øverst på lerretet, mens punktet \((\text{width}, \text{height})\) er punktet til høyre nederst. For et lerret med bredde 400 og høyde på 200, får hjørnene koordinatene under:
I eksempelet under har vi tegnet noen punkter på lerretet for å illustrere koordinatsystemet. Vindusstørrelsen ved bruk av uib_inf100_graphics.simple
er 400x400 som standard.
from uib_inf100_graphics.simple import canvas, display
# polygon defined by four (x, y) coordinates (the corners)
canvas.create_polygon(200, 50,
350, 200,
200, 350,
50, 200,
outline="gray",
fill="")
# draw labels on the same points as corners of polygon
canvas.create_text(200, 50, text="(200, 50)")
canvas.create_text(350, 200, text="(350, 200)")
canvas.create_text(200, 350, text="(200, 350)")
canvas.create_text(50, 200, text="(50, 200)")
# x-label with arrow
canvas.create_text(180, 20, text="x", anchor="se")
canvas.create_line(180, 20, 185, 40, arrow="last")
# y-label with arrow
canvas.create_text(220, 20, text="y", anchor="sw")
canvas.create_line(220, 20, 215, 40, arrow="last")
display(canvas)
create_rectangle
Påkrevde parametre (x1, y1, x2, y2).
- De første to parametrene x1 og y1 er koordinatene til ett av rektangelets hjørner, mens de neste to parametrene x2 og y2 er koordinatene til det motsatte hjørnet. Konvensjon tilsier at (x1, y1) er hjørnet til venstre øverst, mens (x2, y2) er hjørnet til høyre nederst.
Valgfrie parametre (outline, fill, width, …).
- Som standard tegnes rektangelet med en svart strek og uten farge i midten. Dette kan endres ved å angi farge-verdier til valgfrie parametrene
outline
ogfill
. Parameterenwidth
kan benyttes for å angi tykkelsen (i antall piksler) til streken som tegnes.
from uib_inf100_graphics.simple import canvas, display
canvas.create_rectangle(10, 20, 390, 90)
canvas.create_rectangle(10, 110, 390, 190, fill='lightGreen')
canvas.create_rectangle(50, 210, 390, 290, fill='#eeaabb',
outline="red", width=3)
canvas.create_rectangle(10, 310, 390, 390, fill='#00308f', width=0)
display(canvas)
create_oval
Påkrevde parametre (x1, y1, x2, y2).
- Plasseringen til en oval spesifiseres ved å angi koordinater som beskriver et tenkt rektangel som omslutter ovalen. De første fire parameterne skal være koordinatene til to motstående hjørner i dette rektangelet.
Valgfrie parametre (outline, fill, width, …).
- Som standard tegnes ovalen med en svart strek og uten farge i midten. Dette kan endres ved å angi farge-verdier til valgfrie parametrene
outline
ogfill
. Parameterenwidth
kan benyttes for å angi tykkelsen (i antall piksler) til streken som tegnes.
from uib_inf100_graphics.simple import canvas, display
canvas.create_oval(10, 20, 390, 90)
canvas.create_rectangle(10, 20, 390, 90)
canvas.create_oval(10, 110, 390, 190, fill='lightGreen')
canvas.create_oval(50, 210, 390, 290, fill='#eeaabb', outline="red", width=3)
canvas.create_oval(10, 310, 390, 390, fill='#00308f', width=0)
display(canvas)
create_line
Påkrevde parametre (x1, y1, x2, y2, … ).
- For å tegne en linje, må vi oppgi koordinatene til to (eller flere) punkter. De første to parameterne er koordinatene til det første punktet, mens de neste to parameterne er koordinatene til det andre punktet (og de to neste er koordinatene til det tredje punktet, og så videre).
- Det er mulig å angi punktene som en liste med koordinater i stedet for én og én koordinat.
Valgfrie parametre (fill, width, arrow, smooth, …).
- Som standard tegnes linjen med en svart strek. Dette kan endres ved å angi farge-verdier til valgfrie parametrene
fill
. Parameterenwidth
kan benyttes for å angi tykkelsen (i antall piksler) til streken som tegnes. - Det er mulig å angi at streken skal starte eller slutte som en pil ved å angi
arrow="first"
,arrow="last"
ellerarrow="both"
(standard erarrow="none"
). - Det er mulig å angi at streken skal tegnes med en glattere kurve ved å angi
smooth=True
.
from uib_inf100_graphics.simple import canvas, display
canvas.create_line(10, 20, 390, 90)
canvas.create_line(10, 110, 390, 190, fill='blue', width=2, arrow='last')
canvas.create_line(10, 210, 390, 290, 50, 290, 390, 210, fill='red')
points = [(10, 310), (390, 390), (50, 390), (390, 310)]
canvas.create_line(points, fill='green', width=5, smooth=True)
display(canvas)
create_polygon
Påkrevde parametre (x1, y1, x2, y2, x3, y3, … ).
- For å tegne en polygon, må vi oppgi koordinatene til tre eller flere punkter. De første to parameterne er koordinatene til det første punktet, mens de neste to parameterne er koordinatene til det andre punktet, og de to neste er koordinatene til det tredje punktet, og så videre. Dette ligner på å tegne en linje, men hvor den siste linjen for å lukke polygonen tegnes automatisk.
- Det er mulig å angi punktene som en liste med koordinater i stedet for én og én koordinat.
Valgfrie parametre (fill, outline, width, smooth, …).
- Som standard tegnes polygonen uten at linjen tegnes, men med en svart fyllfarge. Dette kan endres ved å angi farge-verdier til valgfrie parametrene
fill
ogoutline
. Parameterenwidth
kan benyttes for å angi tykkelsen (i antall piksler) til streken som tegnes. - Det er mulig å angi at streken skal tegnes med en glattere kurve ved å angi
smooth=True
.
from uib_inf100_graphics.simple import canvas, display
canvas.create_polygon(10, 20, 390, 90, 10, 90)
canvas.create_polygon(10, 110, 390, 190, 10, 190,
fill='', outline='red', width=3) # fill='' -> no fill
points = [50, 210, 390, 290, 50, 290, 390, 210]
canvas.create_polygon(points, fill='lightGreen', outline='black', width=1)
points = [(10, 310), (390, 390), (50, 390), (390, 310)]
canvas.create_polygon(points, fill='darkblue', smooth=True)
display(canvas)
create_arc
Påkrevde parametre (x1, y1, x2, y2).
- For å tegne en bue, må vi oppgi koordinatene til to motstående hjørner i et rektangel som omslutter den ovalen buen er en del av. De første to parameterne er koordinatene til det første hjørnet, mens de neste to parameterne er koordinatene til det andre hjørnet. Konvensjon tilsier at (x1, y1) er hjørnet til venstre øverst, mens (x2, y2) er hjørnet til høyre nederst.
Valgfrie parametre (start, extent, fill, outline, width, style, …).
- Det er mulig å angi at buen skal starte på en annen vinkel enn 0 grader ved å angi
start
(standard erstart=0
). Verdien skal oppgis i grader. - Det er mulig å angi hvor stor andel av ovalen buen skal dekke ved angi
extent
(standard erextent=90
). Verdien skal oppgis i grader. - Som standard tegnes buen med en svart strek og uten farge i midten. Dette kan endres ved å angi farge-verdier til valgfrie parametrene
fill
ogoutline
. Parameterenwidth
kan benyttes for å angi tykkelsen (i antall piksler) til streken som tegnes. - Hvordan buen knyttes sammen i endepunktene kan endres ved å angi
style
. Mulige verdier er'pieslice'
(standard),'chord'
og'arc'
.
from uib_inf100_graphics.simple import canvas, display
canvas.create_arc(10, 20, 390, 90, extent=270)
canvas.create_arc(10, 110, 390, 190, start=45, extent=270, fill='lightGreen')
canvas.create_arc(50, 210, 390, 290, start=45, extent=270, style='chord',
fill='#eeaabb', outline='red', width=8)
canvas.create_arc(10, 310, 390, 390, start=45, extent=270, style='arc')
display(canvas)
create_text
Påkrevde parametre (x, y).
- For å skrive tekst, må vi oppgi koordinatene til hvor teksten skal være. Dette punktet kalles for ankeret til teksten.
Valgfrie parametre (text, anchor, font, fill, angle, width, justify, …).
- Selve teksten som skal skrives oppgis ved å angi
text
. - Som standard plasseres teksten slik at ankeret er i midten av teksten. Dette kan endres ved å angi
anchor
. Mulige verdier er'n'
,'ne'
,'e'
,'se'
,'s'
,'sw'
,'w'
,'nw'
og'center'
(standard er'center'
). Hvis for eksempel ankeret er'sw'
, vil teksten plasseres slik at ankerpunktet havner ved det sør-vestlige (nede til venstre) hjørnet av teksten. - Det er mulig å angi hvilken font som skal brukes ved å angi
font
.
Det er flere gyldige formater å angi fonter på. Eksempler:
'TkFixedFont'
er et eksempel på en navngitt font.
- Avhengig av hvilket operativsystem du er på, kan den samme navngitte fonten se forskjellig ut. På Windows er for eksempel ‘TkFixedFont’ en font som heter Courier, mens på Mac er den en font som heter Monaco.
- Disse navngitte fontene er garantert tilgjengelig: ‘TkDefaultFont’, ‘TkTextFont’, ‘TkFixedFont’, ‘TkMenuFont’, ‘TkHeadingFont’, ‘TkCaptionFont’, ‘TkSmallCaptionFont’, og ‘TkIconFont’.
- Avhengig av operativsystem kan det finnes flere navngitte fonter. For å finne ut hvilke navngitte fonter som er tilgjengelige på ditt operativsystem, kan du kjøre følgende kode:
from tkinter import Tk, font
Tk().withdraw()
print(font.names())
- Standard font dersom ingenting er spesifisert eller den spesifiserte fonten ikke blir funnet er er ‘TkDefaultFont’.
('Times new roman', 12, 'italic bold')
er et eksempel på en tupel som beskriver en font.
- Denne tupelen består av tre elementer: navnet på fontfamilien, størrelsen på fonten, og en streng som beskriver hvilke attributter fonten skal ha.
- Mulige attributter: italic, bold, underline og overstrike (kan kombineres med mellomrom). Om du ikke ønsker noen av dem, angi en tom streng
''
. - En font spesifisert på denne måten ser lik ut på alle operativsystemer, såfremt font-familien er installert på den aktuelle maskinen.
- Hvilke font-familier som er tilgjengelige på ulike datamaskiner varierer.
- Disse familiene er nesten alltid tilgjengelig: ‘Helvetica’, ‘Arial’, ‘Times’, ‘Times new roman’, ‘Courier’ og ‘Courier new’.
- Disse familiene er ofte tilgjengelige (ikke alltid på Linux): ‘Symbol’, ‘Verdana’, ‘Georgia’, ‘Comic Sans MS’, ‘Trebuchet MS’, ‘Arial Black’, ‘Impact’.
- Andre fonter kan virke på din maskin, men ikke regn med at det virker alle andre steder.
- For å se en komplett liste av font-familier tilgjengelig på din maskin, kan du kjøre følgende kode:
from tkinter import Tk, font
Tk().withdraw()
print(font.families())
'Arial 20'
er et eksempel på en streng som beskriver en font basert på fontfamilie og størrelse. Merk at fontfamilien ikke kan inneholde mellomrom, så om du ønsker å bruke en font-familie som består av flere ord, må du bruke en font-tupel som beskrevet over.
'Arial 20 italic underline'
er et annet eksempel på en streng som beskriver en fontfamilie, størrelse og attributter. Merk at fontfamilien ikke kan inneholde mellomrom, så om du har behov for det må du bruke en font-tupel som beskrevet over.
- Farge angis med
fill
. - Det er mulig å angi at teksten skal roteres ved å angi
angle
. Verdien skal oppgis i grader. - For å angi maksimal bredde på et avsnitt og bryte teksten over flere linjer automatisk, kan du angi
width
. Tekst som går over flere linjer kan sidejusteres medjustify
(left/center/right).
from uib_inf100_graphics.simple import canvas, display
ax, ay = 200, 50
canvas.create_oval(ax - 5, ay - 5, ax + 5, ay + 5, fill='pink', outline='')
canvas.create_text(ax, ay, text='Hello, world!')
ax, ay = 200, 100
canvas.create_oval(ax - 5, ay - 5, ax + 5, ay + 5, fill='pink', outline='')
canvas.create_text(ax, ay, text='Carpe diem!', anchor='sw')
ax, ay = 200, 150
canvas.create_oval(ax - 5, ay - 5, ax + 5, ay + 5, fill='pink', outline='')
canvas.create_text(ax, ay, text='Ay caramba!', anchor='n', font='TkFixedFont')
ax, ay = 200, 200
canvas.create_text(ax, ay, text="Don't panic!", font=('Courier new', 20, ''))
ax, ay = 200, 250
canvas.create_text(ax, ay, text='Bazinga!', font=('Times', 30, 'italic bold'))
ax, ay = 200, 300
canvas.create_oval(ax - 5, ay - 5, ax + 5, ay + 5, fill='pink', outline='')
canvas.create_text(ax, ay, text='I have a cunning plan!', fill='blue',
anchor='w', angle=-30)
ax, ay = 200, 350
canvas.create_oval(ax - 5, ay - 5, ax + 5, ay + 5, fill='pink', outline='')
canvas.create_text(ax, ay, text='Here it is, your moment of zen',
anchor='ne', justify='right', width=150)
display(canvas)
create_image
Påkrevde parametre (x, y).
- For å tegne et bilde, må vi oppgi koordinatene til hvor bildet skal være. Dette punktet kalles for ankeret til bildet.
Valgfrie parametre (pil_image, anchor, …).
- Bildet som skal tegnes oppgis ved å angi
pil_image
. Dette kan være et bilde som er lastet inn med hjelp avload_image
ellerload_image_http
-funksjonen fra pakken uib_inf100_graphics.helpers. - Som standard plasseres bildet slik at ankeret er i midten av bildet. Dette kan endres ved å angi
anchor
. Mulige verdier er'n'
,'ne'
,'e'
,'se'
,'s'
,'sw'
,'w'
,'nw'
og'center'
(standard er ‘center’). Hvis for eksempel ankeret er ‘sw’, vil bildet plasseres slik at ankerpunktet havner ved det sør-vestlige (nede til venstre) hjørnet av bildet.
from uib_inf100_graphics.simple import canvas, display
from uib_inf100_graphics.helpers import load_image_http, scaled_image
# Image credits: unsplash.com/@tranmautritam
image = load_image_http('https://tinyurl.com/inf100kitten-png')
canvas.create_image(180, 180, pil_image=image)
canvas.create_oval(180 - 3, 180 - 3, 180 + 3, 180 + 3, fill='red', outline='')
smaller_image = scaled_image(image, 0.4)
canvas.create_image(250, 180, pil_image=smaller_image, anchor='nw')
canvas.create_oval(250 - 3, 180 - 3, 250 + 3, 180 + 3, fill='red', outline='')
display(canvas)
Farger
Et par farger er innebygget, som demonstrert i eksemplene over: 'black'
'white'
'gray'
'red'
'green'
'blue'
'lightGreen'
'rosyBrown'
, samt en hel del andre spenstige farger som du finner i dokumentasjonen til tkinter. Vi er imidlertid ikke begrenset til kun disse fargene.
Piksel
I en LED-skjerm (som er en vanlig dataskjerm) tegnes bildet på skjermen ved at hver enkelt piksel (liten prikk på skjermen) får en bestemt farge. Inne i selve skjermen sitter det tre lamper inne i hver piksel: en rød lampe, en grønn lampe og en blå lampe. Når alle tre lampene lyser med maksimal intensitet, ser vi hvitt lys komme ut av pikselen. Dersom ingen av lampene lyser, er pikselen svart. Alle fargene skjermen kan produsere, blir laget av en kombinasjon av lysintensiteter i de tre pikslene.
Hvis man zoomer inn svært tett på dataskjermen, kan man skimte at en hvit piksel ikke faktisk er helt hvit, men består egentlig av en rød, grønn og blå lampe ved siden av hverandre som lyser. Her er et bilde jeg har tatt av musenpekeren min på skjermen:
Om vi zoomer litt inn på bildet, kan vi skimte at hver piksel består av tre lamper: en rød, en grønn og en blå.
Fordi menneskets øye bare er i stand til å registrere lyssignaler på rød, grønn og blå frekvens, vil en blanding av røde, grønne og blå lyssignaler være tilstrekkelig for å simulere alle oppfattelser av farge et menneskeøye kan gi. Når menneskeøyet får utslag på alle tre fargekanalene, vil vi oppfatte det som hvitt lys; selv om det egentlig bare er en blanding av rødt, grønt og blått lys, og strengt tatt ikke er en blanding av alle mulige slags lysfrekvenser («ekte» hvitt lys).
Når man kjøper en LED-skjerm på butikken, finnes det ulike fargedypder eller man får oppgitt antall farger skjermen kan vise. Denne spesifikasjonen bestemmes av i hvor mange «trinn» man kan justere intensiteten til hver av de fargede lampene i en piksel. Det har lenge vært vanlig at man bruker 256 slike trinn. En farge i dette systemet kan derfor sees på som tre tall (r, g, b), der hver av r, g og b er et tall mellom 0 og 255.
Selv om nyere og dyre skjermer teknisk sett kan ha flere trinn, bruker som regel software som ikke er rettet spesielt mot high-end bildebehandling fremdeles dette systemet som standard.
Alle farger har en RGB-verdi. I tabellen ser vi at hver farge har en gitt styrke av rød (R), grønn (G) og blå (B), som er et tall mellom 0 og 255. Denne RGB-verdien kan også skrives i heksadesimalt format (se kolonnen Hex), hvor de to første tegnene etter hashtag reprsenterer styrken på rød, de to neste representerer grønn, og de to siste representerer blå sin styrke.
Farge | R | G | B | Hex | Kallenavn |
---|---|---|---|---|---|
0 | 0 | 0 | #000000 |
black |
|
255 | 0 | 0 | #ff0000 |
red |
|
0 | 255 | 0 | #00ff00 |
green1 |
|
0 | 0 | 255 | #0000ff |
blue |
|
255 | 255 | 0 | #ffff00 |
yellow |
|
0 | 255 | 255 | #00ffff |
cyan |
|
255 | 0 | 255 | #ff00ff |
magenta |
|
255 | 255 | 255 | #ffffff |
white |
|
128 | 128 | 128 | #808080 |
gray |
|
128 | 0 | 0 | #800000 |
maroon |
|
255 | 140 | 0 | #ff8c00 |
dark orange |
|
224 | 227 | 206 | #e0e3ce |
- | |
248 | 249 | 245 | #f8f9f5 |
- |
For flere farger, se for eksempel listen over farger (A-F) på Wikipedia, eller prøv RGB-kalkulatoren til w3schools.com.
Vårt rammeverk for grafikk kan tolke alle RGB-verdier skrevet i hex-format.
Tekst i boks
For enkelhets skyld har vi laget en hjelpefunksjon som kan brukes til å tegne tekst midt i et rektangel, og som også gjør teksten så stor som mulig innenfor rektangelet. Denne funksjonen heter text_in_box
og må importeres fra pakken uib_inf100_graphics.helpers.
Påkrevde parametre (canvas, x1, y1, x2, y2, text).
canvas
er lerretet som skal tegnes på.x1, y1
er koordinatene til det øverste venstre hjørnet i rektangelet.x2, y2
er koordinatene til det nederste høyre hjørnet i rektangelet.text
er strengen som skal skrives.
Valgfrie parametre (font, fit_mode, padding, min_font_size, justify, align, fill, …).
font
er fonten som skal benyttes. Merk at størrelsen på fonten vil bli ignorert, men må likevel spesifiseres. Les mer om fonter i avsnittet om create_text over.fit_mode
er en streng som angir hvordan teksten skal tilpasses rektangelet. Mulige verdier er'contain'
(standard),'fill'
,'height'
og'width'
.padding
er minimum antall piksler som skal være mellom teksten og kanten av rektangelet (standard 0).min_font_size
er minimum størrelse på fonten som skal brukes. Dersom teksten ikke får plass med denne fontstørrelsen, vil teksten gå utenfor området sitt (standard 1).justify
er en streng som angir hvordan teksten skal justeres horisontalt innenfor rektangelet. Mulige verdier er'left'
,'center'
(standard) og'right'
.align
er en streng som angir hvordan teksten skal justeres vertikalt innenfor rektangelet. Mulige verdier er'top'
,'center'
(standard) og'bottom'
.fill
er fargen teksten skal ha.
from uib_inf100_graphics.simple import canvas, display
from uib_inf100_graphics.helpers import text_in_box
text = "Hello, world!"
# First example
canvas.create_rectangle(100, 20, 300, 70)
text_in_box(canvas, 100, 20, 300, 70, text)
# Named font and padding.
canvas.create_rectangle(100, 120, 300, 170)
text_in_box(canvas, 100, 120, 300, 170, text,
font="TkFixedFont",
justify="left",
padding=15)
# System installed font family name, fill color and fit_mode.
canvas.create_rectangle(100, 200, 300, 270)
text_in_box(canvas, 100, 200, 300, 270, text,
font=("Times new roman", 1, ""),
fit_mode='height', # fit_mode='height' ignores width of rectangle
fill="blue")
# Multiline text, font style, justification.
multiline_text = text+"\n"+text+" "+text+"\n"+text
canvas.create_rectangle(100, 320, 300, 370)
text_in_box(canvas, 100, 320, 300, 370, multiline_text,
font="Arial 42 bold italic overstrike underline",
justify="right", # justify is 'left', 'center' or 'right'
padding=5)
display(canvas)
Bilde i boks
For enkelhets skyld har vi laget en hjelpefunksjon som kan brukes til å tegne et bilde midt i et rektangel, og som også skalerer bildet slik at det passer innenfor rektangelet. Denne funksjonen heter image_in_box
og må importeres fra pakken uib_inf100_graphics.helpers.
Påkrevde parametre (canvas, x1, y1, x2, y2, pil_image).
canvas
er lerretet som skal tegnes på.x1, y1
er koordinatene til det øverste venstre hjørnet i rektangelet..x2, y2
er koordinatene til det nederste høyre hjørnet i rektangeletpil_image
er bildet som skal tegnes. Dette kan være et bilde som er lastet inn med hjelp avload_image
ellerload_image_http
-funksjonen fra pakken uib_inf100_graphics.helpers.
Valgfrie parametre (fit_mode, antialias).
fit_mode
er en streng som angir hvordan bildet skal tilpasses rektangelet. Mulige verdier er'contain'
(standard),'fill'
,'crop'
og'stretch'
.antialias
er en boolsk verdi som angir om bildet skal antialiaseres (standardTrue
). Antialiasering er en teknikk som gjør at bildet ser skarpere ut når det skaleres ned, men bruker mer tid/prosessorkraft.
from uib_inf100_graphics.simple import canvas, display
from uib_inf100_graphics.helpers import load_image_http, image_in_box
# Image credits: unsplash.com/@tranmautritam
image = load_image_http('https://tinyurl.com/inf100kitten-png')
image_in_box(canvas, 20, 40, 180, 180, image)
canvas.create_rectangle(20, 40, 180, 180, outline='red', width=2)
canvas.create_text(100, 35, text="fit_mode='contain'", anchor='s')
image_in_box(canvas, 20, 220, 180, 360, image, fit_mode='crop')
canvas.create_rectangle(20, 220, 180, 360, outline='red', width=2)
canvas.create_text(100, 215, text="fit_mode='crop'", anchor='s')
image_in_box(canvas, 220, 40, 380, 180, image, fit_mode='stretch')
canvas.create_rectangle(220, 40, 380, 180, outline='red', width=2)
canvas.create_text(300, 35, text="fit_mode='stretch'", anchor='s')
image_in_box(canvas, 220, 220, 380, 360, image, fit_mode='fill')
canvas.create_rectangle(220, 220, 380, 360, outline='red', width=2)
canvas.create_text(300, 215, text="fit_mode='fill'", anchor='s')
display(canvas)
Eksempel: buss
I videoen vises litt av tankeprosessen for å tegne en enkel buss. Her er koden som blir skrevet:
from uib_inf100_graphics.simple import canvas, display
# Body
canvas.create_rectangle(100, 100, 300, 200, fill="yellow")
# Windows
canvas.create_rectangle(100, 110, 150, 160, fill="white")
canvas.create_rectangle(260, 110, 290, 140, fill="white")
canvas.create_rectangle(220, 110, 250, 140, fill="white")
# Door
canvas.create_rectangle(160, 130, 210, 200, fill="white")
canvas.create_line(185, 130, 185, 200)
# Wheels
canvas.create_oval(120, 190, 140, 210, fill="black")
canvas.create_oval(260, 190, 280, 210, fill="black")
display(canvas)