Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env lua
- -- Lua
- -- Kuvan mitat.
- LEVEYS = 192
- KORKEUS = 128
- KOKO = 3 * LEVEYS * KORKEUS
- -- Tämä funktio pakottaa keskimmäisen kolmesta argumentista kahden muun
- -- välille. Se toimii oikein, kun viimeinen on suurempi kuin ensimmäinen.
- function valille(ala, arvo, yla)
- if arvo < ala then arvo = ala end
- if arvo > yla then arvo = yla end
- return arvo
- end
- -- Tämä funktio luo uuden värin.
- -- r = punainen, g= vihreä, b = sininen.
- -- Sallitut arvot ovat 0-255.
- function uusiVari(r, g, b)
- r, g, b = valille(0, r, 255), valille(0, g, 255), valille(0, b, 255)
- return {r = math.floor(r), g = math.floor(g), b = math.floor(b)}
- end
- -- Tämä taulukko on kuvan prototyyppi. Metataulukkomäärittelyn ja __index-
- -- metametodin avulla sen ominaisuudet löytyvät metodilla Kuva:uusi
- -- muodostetuista kuvista.
- Kuva = {
- data = {}
- }
- for i = 1, KOKO do table.insert(Kuva.data, 0) end
- Kuva.__index = Kuva
- -- Tämä funktio on uuden kuvan muodostin. Puuttuva data täytetään arvoilla
- -- prototyypistä.
- function Kuva:uusi(data)
- data = data or {}
- local uusi = {}
- local pituus = #data
- local puuttuu = KOKO - pituus
- for i = 1, puuttuu do
- table.insert(data, Kuva.data[pituus+i])
- end
- assert(#data == KOKO)
- uusi.data = data
- setmetatable(uusi, Kuva)
- return uusi
- end
- -- Tämä funktio hakee yhden pisteen värin. Jos x ja y ovat kuvan
- -- ulkopuolella, se palauttaa lähimmän pisteen kuvan reunalta.
- function Kuva:hae(x, y)
- local x = math.floor(valille(1, x, LEVEYS))
- local y = math.floor(valille(1, y, KORKEUS))
- local i0 = 3 * (LEVEYS * (KORKEUS - y) + x) - 2
- return uusiVari(self.data[i0], self.data[i0+1], self.data[i0+2])
- end
- -- Tämä metodi asettaa yhden pisteen värin.
- function Kuva:aseta(x, y, vari)
- x, y = math.floor(x), math.floor(y)
- if 1 <= x and x <= LEVEYS and 1 <= y and y <= KORKEUS then
- local i0 = 3 * (LEVEYS * (KORKEUS - y) + x) - 2
- self.data[i0] = vari.b
- self.data[i0+1] = vari.g
- self.data[i0+2] = vari.r
- end
- end
- -- Tämä funktio tekee mallikuvan pohjalta lopullisen teoksen.
- function muokkaa(malli)
- local teos = Kuva:uusi()
- -- Tämä silmukka kopioi mallikuvan teos-kuvaan siten, että kopioiden
- -- koko on yksi neljännes alkuperäisestä ja ne on peilattu kohdekuvan
- -- eri neljänneksiin väritettyinä.
- for x = 1, LEVEYS, 2 do
- for y = 1, KORKEUS, 2 do
- -- Tämä osa hakee neljän pikselin alueen.
- local v0 = malli:hae(x, y)
- local v1 = malli:hae(x+1, y)
- local v2 = malli:hae(x+1, y+1)
- local v3 = malli:hae(x, y+1)
- -- Tämä laskee pikselien keskiarvon.
- v0.r = math.floor((v0.r + v1.r + v2.r + v3.r) / 4)
- v0.g = math.floor((v0.g + v1.g + v2.g + v3.g) / 4)
- v0.b = math.floor((v0.b + v1.b + v2.b + v3.b) / 4)
- -- Tämä asettaa eri väriset pisteet eri neljänneksiin.
- local px, py = math.ceil(x/2), math.ceil(y/2)
- local pxPeili, pyPeili = LEVEYS + 1 - px, KORKEUS + 1 - py
- teos:aseta(px, py, v0)
- teos:aseta(pxPeili, py, uusiVari(v0.r/2, v0.g, v0.b))
- teos:aseta(pxPeili, pyPeili, uusiVari(v0.r, v0.g/2, v0.b))
- teos:aseta(px, pyPeili, uusiVari(v0.r, v0.g, v0.b/2))
- end
- end
- return teos
- end
- -- Tämä osa lukee mallikuvan.
- local malliTiedosto = io.open('malli.bmp', 'rb')
- if not malliTiedosto then
- error "Tiedostoa malli.bmp ei voitu lukea."
- end
- local data = malliTiedosto:read('*all')
- if #data ~= 54 + KOKO then
- error "Tiedosto malli.bmp on viallinen."
- end
- malliTiedosto:close()
- local otsikko = data:sub(1, 54)
- local tavut = {}
- for i = 55, #data do
- table.insert(tavut, data:byte(i))
- end
- assert(#tavut == KOKO)
- -- Tämä muokkaa sen.
- local teos = muokkaa(Kuva:uusi(tavut))
- -- Tämä kirjoittaa uuden kuvan tiedostoon.
- local teosTiedosto = io.open('teos.bmp', 'wb')
- if not teosTiedosto then
- error "Tiedostoon teos.bmp ei voitu kirjoittaa."
- end
- teosTiedosto:write(otsikko)
- for i = 1, #teos.data do
- teos.data[i] = string.char(teos.data[i])
- end
- teosTiedosto:write(table.concat(teos.data))
- teosTiedosto:close()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement