Advertisement
Guest User

Putkakilpailuun Luaa

a guest
Dec 10th, 2011
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.28 KB | None | 0 0
  1. #!/usr/bin/env lua
  2.  
  3. -- Lua
  4.  
  5. -- Kuvan mitat.
  6. LEVEYS  = 192
  7. KORKEUS = 128
  8. KOKO    = 3 * LEVEYS * KORKEUS
  9.  
  10. -- Tämä funktio pakottaa keskimmäisen kolmesta argumentista kahden muun
  11. -- välille. Se toimii oikein, kun viimeinen on suurempi kuin ensimmäinen.
  12. function valille(ala, arvo, yla)
  13.     if arvo < ala then arvo = ala end
  14.     if arvo > yla then arvo = yla end
  15.     return arvo
  16. end
  17.  
  18. -- Tämä funktio luo uuden värin.
  19. -- r = punainen, g= vihreä, b = sininen.
  20. -- Sallitut arvot ovat 0-255.
  21.  
  22. function uusiVari(r, g, b)
  23.     r, g, b = valille(0, r, 255), valille(0, g, 255), valille(0, b, 255)
  24.     return {r = math.floor(r), g = math.floor(g), b = math.floor(b)}
  25. end
  26.  
  27. -- Tämä taulukko on kuvan prototyyppi. Metataulukkomäärittelyn ja __index-
  28. -- metametodin avulla sen ominaisuudet löytyvät metodilla Kuva:uusi
  29. -- muodostetuista kuvista.
  30.  
  31. Kuva = {
  32.     data = {}
  33. }
  34.  
  35. for i = 1, KOKO do table.insert(Kuva.data, 0) end
  36. Kuva.__index = Kuva
  37.  
  38. -- Tämä funktio on uuden kuvan muodostin. Puuttuva data täytetään arvoilla
  39. -- prototyypistä.
  40. function Kuva:uusi(data)
  41.     data = data or {}
  42.     local uusi = {}
  43.     local pituus = #data
  44.     local puuttuu = KOKO - pituus
  45.     for i = 1, puuttuu do
  46.         table.insert(data, Kuva.data[pituus+i])  
  47.     end
  48.     assert(#data == KOKO)
  49.     uusi.data = data
  50.     setmetatable(uusi, Kuva)
  51.     return uusi
  52. end
  53.  
  54. -- Tämä funktio hakee yhden pisteen värin. Jos x ja y ovat kuvan
  55. -- ulkopuolella, se palauttaa lähimmän pisteen kuvan reunalta.
  56. function Kuva:hae(x, y)
  57.     local x = math.floor(valille(1, x, LEVEYS))
  58.     local y = math.floor(valille(1, y, KORKEUS))
  59.     local i0 = 3 * (LEVEYS * (KORKEUS - y) + x) - 2
  60.     return uusiVari(self.data[i0], self.data[i0+1], self.data[i0+2])
  61. end
  62.  
  63. -- Tämä metodi asettaa yhden pisteen värin.
  64. function Kuva:aseta(x, y, vari)
  65.     x, y = math.floor(x), math.floor(y)
  66.     if 1 <= x and x <= LEVEYS and 1 <= y and y <= KORKEUS then
  67.         local i0 = 3 * (LEVEYS * (KORKEUS - y) + x) - 2
  68.         self.data[i0]   = vari.b
  69.         self.data[i0+1] = vari.g
  70.         self.data[i0+2] = vari.r
  71.     end
  72. end
  73.  
  74. -- Tämä funktio tekee mallikuvan pohjalta lopullisen teoksen.
  75. function muokkaa(malli)
  76.     local teos = Kuva:uusi()
  77.     -- Tämä silmukka kopioi mallikuvan teos-kuvaan siten, että kopioiden
  78.     -- koko on yksi neljännes alkuperäisestä ja ne on peilattu kohdekuvan
  79.     -- eri neljänneksiin väritettyinä.
  80.     for x = 1, LEVEYS, 2 do
  81.         for y = 1, KORKEUS, 2 do
  82.             -- Tämä osa hakee neljän pikselin alueen.
  83.             local v0 = malli:hae(x, y)
  84.             local v1 = malli:hae(x+1, y)
  85.             local v2 = malli:hae(x+1, y+1)
  86.             local v3 = malli:hae(x, y+1)
  87.        
  88.             -- Tämä laskee pikselien keskiarvon.
  89.             v0.r = math.floor((v0.r + v1.r + v2.r + v3.r) / 4)
  90.             v0.g = math.floor((v0.g + v1.g + v2.g + v3.g) / 4)
  91.             v0.b = math.floor((v0.b + v1.b + v2.b + v3.b) / 4)
  92.  
  93.             -- Tämä asettaa eri väriset pisteet eri neljänneksiin.
  94.             local px, py = math.ceil(x/2), math.ceil(y/2)
  95.             local pxPeili, pyPeili = LEVEYS + 1 - px, KORKEUS + 1 - py
  96.             teos:aseta(px, py, v0)
  97.             teos:aseta(pxPeili, py, uusiVari(v0.r/2, v0.g, v0.b))
  98.             teos:aseta(pxPeili, pyPeili, uusiVari(v0.r, v0.g/2, v0.b))
  99.             teos:aseta(px, pyPeili, uusiVari(v0.r, v0.g, v0.b/2))
  100.         end
  101.     end
  102.     return teos
  103. end
  104.  
  105. -- Tämä osa lukee mallikuvan.
  106. local malliTiedosto = io.open('malli.bmp', 'rb')
  107. if not malliTiedosto then
  108.     error "Tiedostoa malli.bmp ei voitu lukea."
  109. end
  110.  
  111. local data = malliTiedosto:read('*all')
  112. if #data ~= 54 + KOKO then
  113.     error "Tiedosto malli.bmp on viallinen."
  114. end
  115. malliTiedosto:close()
  116.  
  117. local otsikko = data:sub(1, 54)
  118. local tavut = {}
  119.  
  120. for i = 55, #data do
  121.     table.insert(tavut, data:byte(i))
  122. end
  123. assert(#tavut == KOKO)
  124.  
  125. -- Tämä muokkaa sen.
  126. local teos = muokkaa(Kuva:uusi(tavut))
  127.  
  128. -- Tämä kirjoittaa uuden kuvan tiedostoon.
  129. local teosTiedosto = io.open('teos.bmp', 'wb')
  130. if not teosTiedosto then
  131.     error "Tiedostoon teos.bmp ei voitu kirjoittaa."
  132. end
  133.  
  134. teosTiedosto:write(otsikko)
  135.  
  136. for i = 1, #teos.data do
  137.     teos.data[i] = string.char(teos.data[i])
  138. end
  139.  
  140. teosTiedosto:write(table.concat(teos.data))
  141. teosTiedosto:close()
  142.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement