This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Mads's profile picture

Loading Bitmap images. (BMP)

Started by Mads, 13 February 2013 - 12:50 AM
Mads #1
Posted 13 February 2013 - 01:50 AM
This "API" allows you to load BMP images with one function call. This means that you can use images that you created in your favorite image editor, without any conversion. It returns an image which can be used in the paint program, and can be used with the paintutils API.

To get it, copy this code:
Spoiler


colorRGB = {
{r = 221, g = 221, b = 221, code = "0"},
{r = 219, g = 125, b = 62, code = "1"},
{r = 179, g = 80, b = 188, code = "2"},
{r = 107, g = 138, b = 201, code = "3"},
{r = 177, g = 166, b = 39, code = "4"},
{r = 65, g = 174, b = 56, code = "5"},
{r = 208, g = 132, b = 153, code = "6"},
{r = 64, g = 64, b = 64, code = "7"},
{r = 154, g = 161, b = 161, code = "8"},
{r = 46, g = 110, b = 137, code = "9"},
{r = 126, g = 61, b = 181, code = "a"},
{r = 46, g = 56, b = 141, code = "b"},
{r = 79, g = 50, b = 31, code = "c"},
{r = 53, g = 70, b = 27, code = "d"},
{r = 150, g = 52, b = 48, code = "e"},
{r = 25, g = 22, b = 22, code = "f"}
}

function readWORD(str, offset)
local loByte = str:byte(offset)
local hiByte = str:byte(offset + 1)
return hiByte * 256 + loByte
end

function readDWORD(str, offset)
local loWord = readWORD(str, offset)
local hiWord = readWORD(str, offset + 2)
return hiWord * 65536 + loWord
end

function get4BitColor(r, g, B)/>
for k, v in ipairs(colorRGB) do
-- print(r .. "/" .. v.r .. " " .. g .. "/" .. v.g .. " " .. b .. "/" .. v.B)/>

local lookVel = 10

if r > v.r - lookVel and r < v.r + lookVel and g > v.g - lookVel and g < v.g + lookVel and b > v.b - lookVel and b < v.b + lookVel then
return v.code
end
end

return " "
end

function loadBitmap(path)
local pixels = {}

local f = assert(io.open(path, "rb"))
local bytecode = ""
local byte = f:read()

while byte ~= nil do
bytecode = bytecode .. string.char(byte)
byte = f:read()
end

f:close()

-- Parse BITMAPFILEHEADER
local offset = 1
local bfType = readWORD(bytecode, offset)
if(bfType ~= 0x4D42) then
print("Not a bitmap file (Invalid BMP magic value)")
error()
end
local offBits = readWORD(bytecode, offset + 10)

-- Parse BITMAPINFOHEADER
offset = 15; -- BITMAPFILEHEADER is 14 bytes long
local width = readDWORD(bytecode, offset + 4)
local height = readDWORD(bytecode, offset + 8)
local bitCount = readWORD(bytecode, offset + 14)
local compression = readDWORD(bytecode, offset + 16)

if(bitCount ~= 24) then
print("Only 24-bit bitmaps supported (Is " .. bitCount .. "bpp)")
error()
end

if(compression ~= 0) then
print("Only uncompressed bitmaps supported (Compression type is " .. compression .. ")")
error()
end

print("Found width " .. width .. "*" .. height)

-- Parse image
for y = height - 1, 0, -1 do
offset = offBits + (width * bitCount / 8) * y + 1

for x = 1, width do
if type(pixels[x]) ~= "table" then
pixels[x] = {}
end

local b = bytecode:byte(offset)
local g = bytecode:byte(offset + 1)
local r = bytecode:byte(offset + 2)
offset = offset + 3

-- print("RGB: " .. r .. " " .. g .. " " .. B)/>

pixels[x][height - y] = get4BitColor(r, g, B)/>
end
end

-- Generate the image
local tmpF = io.open("_tmp.temp", "w")

for y = 1, height do
for x = 1, width do
tmpF:write(pixels[x][y])
end

tmpF:write("\n")
end

tmpF:close()

if paintutils then
local img = paintutils.loadImage("_tmp.temp")
fs.delete("_tmp.temp")

return img
end
end

Or use this command:
pastebin get VT4gS3Ja bmploader

Then load the API with

os.loadAPI("bmploader")

Usage:

bmploader.loadBitmap(path:string) -- Returns the image.

NOTE: All images MUST be 24-bit.

When making the images, remember to keep inside atleast +-10 of the RGB values, which you can see here:


Here is a test image:
pastebin get r9FNQYUF test.bmp

Please leave some feedback!

EDIT: Apparently Pastebin doesn't like keeping the right format, so you will have to use a reliable source for downloading the images, or make them yourself.
Dlcruz129 #2
Posted 13 February 2013 - 04:14 AM
Very nice!
PixelToast #3
Posted 13 February 2013 - 04:22 AM
could you make a bitmap saver?
Kingdaro #4
Posted 13 February 2013 - 04:23 AM
Great work! Though I'm only a little disapproving of this hardcore fourth wall destruction. :P/>
Mads #5
Posted 13 February 2013 - 05:30 AM
could you make a bitmap saver?

I suppose yes. I'll start working on that, I just have to look into it abit more.