RosettaCodeData/Task/Bitmap-Write-a-PPM-file/Lua/bitmap-write-a-ppm-file-1.lua

107 lines
2.6 KiB
Lua

-- helper function, simulates PHP's array_fill function
local array_fill = function(vbegin, vend, value)
local t = {}
for i=vbegin, vend do
t[i] = value
end
return t
end
Bitmap = {}
Bitmap.__index = Bitmap
function Bitmap.new(width, height)
local self = {}
setmetatable(self, Bitmap)
local white = array_fill(0, width, {255, 255, 255})
self.data = array_fill(0, height, white)
self.width = width
self.height = height
return self
end
function Bitmap:writeRawPixel(file, c)
local dt
dt = string.format("%c", c)
file:write(dt)
end
function Bitmap:writeComment(fh, ...)
local strings = {...}
local str = ""
local result
for _, s in pairs(strings) do
str = str .. tostring(s)
end
result = string.format("# %s\n", str)
fh:write(result)
end
function Bitmap:writeP6(filename)
local fh = io.open(filename, 'w')
if not fh then
error(string.format("failed to open %q for writing", filename))
else
fh:write(string.format("P6 %d %d 255\n", self.width, self.height))
self:writeComment(fh, "automatically generated at ", os.date())
for _, row in pairs(self.data) do
for _, pixel in pairs(row) do
self:writeRawPixel(fh, pixel[1])
self:writeRawPixel(fh, pixel[2])
self:writeRawPixel(fh, pixel[3])
end
end
end
end
function Bitmap:fill(x, y, width, height, color)
width = (width == nil) and self.width or width
height = (height == nil) and self.height or height
width = width + x
height = height + y
for i=y, height do
for j=x, width do
self:setPixel(j, i, color)
end
end
end
function Bitmap:setPixel(x, y, color)
if x >= self.width then
--error("x is bigger than self.width!")
return false
elseif x < 0 then
--error("x is smaller than 0!")
return false
elseif y >= self.height then
--error("y is bigger than self.height!")
return false
elseif y < 0 then
--error("y is smaller than 0!")
return false
end
self.data[y][x] = color
return true
end
function example_colorful_stripes()
local w = 260*2
local h = 260*2
local b = Bitmap.new(w, h)
--b:fill(2, 2, 18, 18, {240,240,240})
b:setPixel(0, 15, {255,68,0})
for i=1, w do
for j=1, h do
b:setPixel(i, j, {
(i + j * 8) % 256,
(j + (255 * i)) % 256,
(i * j) % 256
}
);
end
end
return b
end
example_colorful_stripes():writeP6('p6.ppm')