diff --git a/lib/image.lua b/lib/image.lua index 4c28f38c..c8c77d91 100644 --- a/lib/image.lua +++ b/lib/image.lua @@ -4,11 +4,149 @@ local gpu = require("component").gpu local image = {} ---------------------------------------------------------------------------------------------------------------------- - local transparentSymbol = "#" -function image.load(path) +--------------------Все, что касается сжатого формата изображений---------------------------------------------------------------------------------- + +--OC image format .ocif by Pirnogion +local ocif_signature1 = 0x896F6369 +local ocif_signature2 = 0x00661A0A --7 bytes: 89 6F 63 69 66 1A 0A +local ocif_signature_expand = { string.char(0x89), string.char(0x6F), string.char(0x63), string.char(0x69), string.char(0x66), string.char(0x1A), string.char(0x0A) } + +local BYTE = 8 +local NULL_CHAR = 0 + +local imageAPI = {} + +local function readBytes(file, bytes) + local readedByte = 0 + local readedNumber = 0 + for i = bytes, 1, -1 do + readedByte = string.byte( file:read(1) or NULL_CHAR ) + readedNumber = readedNumber + bit32.lshift(readedByte, i*8-8) + end + + return readedNumber +end + +local function HEXtoRGB(color) + local rr = bit32.rshift( color, 16 ) + local gg = bit32.rshift( bit32.band(color, 0x00ff00), 8 ) + local bb = bit32.band(color, 0x0000ff) + + return rr, gg, bb +end + +local function encodePixel(hexcolor_fg, hexcolor_bg, char) + local rr_fg, gg_fg, bb_fg = HEXtoRGB( hexcolor_fg ) + local rr_bg, gg_bg, bb_bg = HEXtoRGB( hexcolor_bg ) + local ascii_char1, ascii_char2 = string.byte( char, 1, 2 ) + + ascii_char1 = ascii_char1 or NULL_CHAR + ascii_char2 = ascii_char2 or NULL_CHAR + + return rr_fg, gg_fg, bb_fg, rr_bg, gg_bg, bb_bg, ascii_char1, ascii_char2 +end + +local function decodeChar(char1, char2) + if ( char1 ~= 0 and char2 ~= 0 ) then + return string.char( char1, char2 ) + elseif ( char1 ~= 0) then + return string.char( char1 ) + elseif ( char2 ~= 0 ) then + return string.char( char2 ) + end +end + +--Чтение сжатого формата +local function loadJPG(path) + local image = {} + local file = io.open(path, "rb") + + local signature1, signature2 = readBytes(file, 4), readBytes(file, 3) + if ( signature1 ~= ocif_signature1 or signature2 ~= ocif_signature2 ) then + file:close() + return nil + end + + image.width = readBytes(file, 1) + image.height = readBytes(file, 1) + image.depth = readBytes(file, 1) + + for y = 1, image.height, 1 do + table.insert( image, {} ) + for x = 1, image.width, 1 do + table.insert( image[y], {} ) + image[y][x].fg = readBytes(file, 3) + image[y][x].bg = readBytes(file, 3) + image[y][x].char = decodeChar(readBytes(file, 1), readBytes(file, 1)) + end + end + + file:close() + + return image +end + +--Рисование сжатого формата +local function drawJPG(x, y, image2) + x = x - 1 + y = y - 1 + for j = 1, image2.height, 1 do + for i = 1, image2.width, 1 do + + if image2[j][i].char ~= transparentSymbol then + if i > 1 then + if image2[j][i - 1].bg ~= image2[j][i].bg then + gpu.setBackground(image2[j][i].bg) + end + if image2[j][i - 1].fg ~= image2[j][i].fg then + gpu.setBackground(image2[j][i].bg) + end + else + gpu.setBackground(image2[j][i].bg) + gpu.setForeground(image2[j][i].fg) + end + + gpu.set(x + i, y + j, image2[j][i].char) + end + end + end +end + +--Сохранение ДЖПГ в файл из существующего массива +function image.saveJPG(path, image) + + -- Удаляем файл, если есть + -- И делаем папку к нему + fs.remove(path) + fs.makeDirectory(fs.path(path)) + + local file = io.open(path, "w") + + --print("width = ", image.width) + + file:write( table.unpack(ocif_signature_expand) ) + file:write( string.char( image.width ) ) + file:write( string.char( image.height ) ) + file:write( string.char( image.depth ) ) + + for y = 1, image.height, 1 do + for x = 1, image.width, 1 do + local encodedPixel = { encodePixel( image[y][x].fg, image[y][x].bg, image[y][x].char ) } + for i = 1, #encodedPixel do + file:write( string.char( encodedPixel[i] ) ) + end + end + end + + file:close() +end + +---------------------------Все, что касается несжатого формата------------------------------------------------------- + +--Загрузка ПНГ +local function loadPNG(path) local file = io.open(path, "r") local massiv = {} @@ -35,21 +173,216 @@ function image.load(path) return massiv end -function image.draw(x, y, massivSudaPihay) +--Отрисовка ПНГ +local function drawPNG(x, y, massivSudaPihay) x = x - 1 y = y - 1 for j = 1, #massivSudaPihay do for i = 1, #massivSudaPihay[j] do if massivSudaPihay[j][i][1] and massivSudaPihay[j][i][2] and massivSudaPihay[j][i][3] ~= transparentSymbol then - gpu.setBackground(massivSudaPihay[j][i][1]) - gpu.setForeground(massivSudaPihay[j][i][2]) + + if i > 1 then + if massivSudaPihay[j][i - 1][1] ~= massivSudaPihay[j][i][1] then + gpu.setBackground(massivSudaPihay[j][i][1]) + end + if massivSudaPihay[j][i - 1][2] ~= massivSudaPihay[j][i][2] then + gpu.setForeground(massivSudaPihay[j][i][2]) + end + else + gpu.setBackground(massivSudaPihay[j][i][1]) + gpu.setForeground(massivSudaPihay[j][i][2]) + end + gpu.set(x + i, y + j, massivSudaPihay[j][i][3]) end end end end +-- Сохранение существующего массива ПНГ в файл +function image.savePNG(path, MasterPixels) + -- Удаляем файл, если есть + -- И делаем папку к нему + fs.remove(path) + fs.makeDirectory(fs.path(path)) + local f = io.open(path, "w") + + for j=1,imageHeight do + for i=1,imageWidth do + f:write(HEXtoSTRING(MasterPixels[j][i][1])," ",HEXtoSTRING(MasterPixels[j][i][2])," ",MasterPixels[j][i][3]," ") + end + f:write("\n") + end + + f:close() +end + +---------------------Глобальные функции отрисовки--------------------------------------------------------- + +--Конвертер из PNG в JPG +function image.PNGtoJPG(PNGMassiv) + local JPGMassiv = {} + local width, height = 0, 0 + + --Сохраняем пиксели + for j = 1, #PNGMassiv do + JPGMassiv[j] = {} + width = 0 + for i = 1, #PNGMassiv[j] do + JPGMassiv[j][i] = {} + JPGMassiv[j][i]["bg"] = PNGMassiv[j][i][1] + JPGMassiv[j][i]["fg"] = PNGMassiv[j][i][2] + JPGMassiv[j][i]["char"] = PNGMassiv[j][i][3] + width = width + 1 + end + height = height + 1 + end + + JPGMassiv["width"] = width + JPGMassiv["height"] = height + JPGMassiv["depth"] = 8 + + return JPGMassiv +end + +-- Просканировать файловую систему на наличие .PNG +-- И сохранить рядом с ними аналогичную копию в формате .JPG +-- Осторожно, функция для дебага и знающих людей +-- С кривыми ручками сюда не лезь +function image.convertAllPNGtoJPG(path) + local list = ecs.getFileList(path) + for key, file in pairs(list) do + if fs.isDirectory(path.."/"..file) then + image.convertAllPNGtoJPG(path.."/"..file) + else + if ecs.getFileFormat(file) == ".png" or ecs.getFileFormat(file) == ".PNG" then + print("Найден .PNG в директории \""..path.."/"..file.."\"") + print("Загружаю этот файл...") + PNGFile = loadPNG(path.."/"..file) + print("Загрузка завершена!") + print("Конвертация в JPG начата...") + JPGFile = image.PNGtoJPG(PNGFile) + print("Ковертация завершена!") + print("Сохраняю .JPG в той же папке...") + image.saveJPG(path.."/"..ecs.hideFileFormat(file)..".jpg", JPGFile) + print("Сохранение завершено!") + print(" ") + end + end + end +end + +--Загрузка любого изображения из доступных типов +function image.load(path) + + local kartinka = {} + local fileFormat = ecs.getFileFormat(path) + + if string.lower(fileFormat) == ".jpg" then + kartinka["format"] = ".jpg" + kartinka["image"] = loadJPG(path) + elseif string.lower(fileFormat) == ".png" then + kartinka["format"] = ".png" + kartinka["image"] = loadPNG(path) + else + ecs.error("Wrong file format! (not .png or .jpg)") + end + + return kartinka +end + +--Отрисовка этого изображения +function image.draw(x, y, kartinka) + if kartinka.format == ".jpg" then + drawJPG(x, y, kartinka["image"]) + elseif kartinka.format == ".png" then + drawPNG(x, y, kartinka["image"]) + end +end --------------------------------------------------------------------------------------------------------------------- +--image.convertAllPNGtoJPG("") + +-- local test = image.load("System/OS/Icons/Love.jpg") +-- image.draw(2, 2, test) + +-- local cyyyyka = image.load("1.png.png") +-- image.draw(2, 2, cyyyyka) + + + + +-- function imageAPI.initGlobal() +-- local prev = _G.global_images +-- _G.global_images = {} + +-- return _G.global_images, prev +-- end + +-- local test = { +-- ["format"] = ".jpg", +-- ["image"] ={ +-- ["width"] = 8, +-- ["height"] = 4, +-- ["depth"] = 8, +-- { +-- {["fg"]=0x000000, ["bg"]=0xFFFFFF, ["char"]='1'}, +-- {["fg"]=0x000000, ["bg"]=0xFFFFFF, ["char"]='0'}, +-- {["fg"]=0x000000, ["bg"]=0xFFFFFF, ["char"]='1'}, +-- {["fg"]=0x000000, ["bg"]=0xFFFFFF, ["char"]='0'}, +-- {["fg"]=0x000000, ["bg"]=0xFFFFFF, ["char"]='1'}, +-- {["fg"]=0x000000, ["bg"]=0x004980, ["char"]=' '}, +-- {["fg"]=0x000000, ["bg"]=0x004980, ["char"]=' '}, +-- {["fg"]=0x000000, ["bg"]=0x004980, ["char"]=' '} +-- }, +-- { +-- {["fg"]=0x000000, ["bg"]=0x004980, ["char"]=' '}, +-- {["fg"]=0x000000, ["bg"]=0xFFFFFF, ["char"]='1'}, +-- {["fg"]=0x000000, ["bg"]=0xFFFFFF, ["char"]='0'}, +-- {["fg"]=0x000000, ["bg"]=0xFFFFFF, ["char"]='1'}, +-- {["fg"]=0x000000, ["bg"]=0xFFFFFF, ["char"]='0'}, +-- {["fg"]=0x000000, ["bg"]=0xFFFFFF, ["char"]='1'}, +-- {["fg"]=0x000000, ["bg"]=0x004980, ["char"]=' '}, +-- {["fg"]=0x000000, ["bg"]=0x004980, ["char"]=' '} +-- }, +-- { +-- {["fg"]=0x000000, ["bg"]=0x004980, ["char"]=' '}, +-- {["fg"]=0x000000, ["bg"]=0x004980, ["char"]=' '}, +-- {["fg"]=0x000000, ["bg"]=0xFFFFFF, ["char"]='1'}, +-- {["fg"]=0x000000, ["bg"]=0xFFFFFF, ["char"]='0'}, +-- {["fg"]=0x000000, ["bg"]=0xFFFFFF, ["char"]='1'}, +-- {["fg"]=0x000000, ["bg"]=0xFFFFFF, ["char"]='0'}, +-- {["fg"]=0x000000, ["bg"]=0xFFFFFF, ["char"]='1'}, +-- {["fg"]=0x000000, ["bg"]=0x004980, ["char"]=' '} +-- }, +-- { +-- {["fg"]=0x000000, ["bg"]=0xFFFFFF, ["char"]='P'}, +-- {["fg"]=0x000000, ["bg"]=0xFFFFFF, ["char"]='A'}, +-- {["fg"]=0x000000, ["bg"]=0xFFFFFF, ["char"]='S'}, +-- {["fg"]=0x000000, ["bg"]=0xFFFFFF, ["char"]='T'}, +-- {["fg"]=0x000000, ["bg"]=0xFFFFFF, ["char"]='Ж'}, +-- {["fg"]=0x000000, ["bg"]=0xFFFFFF, ["char"]='B'}, +-- {["fg"]=0x000000, ["bg"]=0xFFFFFF, ["char"]='I'}, +-- {["fg"]=0x000000, ["bg"]=0xFFFFFF, ["char"]='N'} +-- }, +-- } +-- } + +-- image.draw(20, 2, test) + + return image + + + + + + + + + + + + +