mirror of
https://github.com/IgorTimofeev/MineOS.git
synced 2026-01-06 11:12:40 +01:00
Big update for Image API and Picture Edit
This commit is contained in:
parent
274cb57ea7
commit
71dfb3c857
@ -6,6 +6,7 @@
|
||||
path = "Path: ",
|
||||
save = "Save",
|
||||
saveAs = "Save as",
|
||||
ok = "Ok",
|
||||
cancel = "Cancel",
|
||||
fileName = "File name",
|
||||
newPicture = "New picture",
|
||||
@ -35,7 +36,7 @@
|
||||
"F - braille tool",
|
||||
" ",
|
||||
"X - switch colors",
|
||||
"D - make colors B/W",
|
||||
"D - reset drawing colors",
|
||||
},
|
||||
tool1 = "Selection tool allows you to select preferred area on image and to perform some operations on it. Green dots mean start and end points (for example, it needs to line rasterization)",
|
||||
fill = "Fill",
|
||||
@ -65,5 +66,24 @@
|
||||
eraseSym = "Erase symbol:",
|
||||
tool7 = "Text tool allows you to type some text data with selected primary color right on your image! It's time to say \"ur mom gay\" to everyone <3",
|
||||
tool8 = "Fill tool allows you to automatically fill areas with selected primary color just like in Paint. Oh God, where is my RAM...?",
|
||||
tool9 = "Braille tool allows you to draw pixels with Braille symbols on your image. Select preferred mini-pixels via menu above, configure transparency affecting and \"Let's go fellas!\""
|
||||
}
|
||||
tool9 = "Braille tool allows you to draw pixels with Braille symbols on your image. Select preferred mini-pixels via menu above, configure transparency affecting and \"Let's go fellas!\"",
|
||||
image = "Image",
|
||||
edit = "Edit",
|
||||
rotate90 = "Rotate by 90 degrees",
|
||||
rotate180 = "Rotate by 180 degrees",
|
||||
rotate270 = "Rotate by 270 degrees",
|
||||
flipVertical = "Flip vertical",
|
||||
flipHorizontal = "Flip horizontal",
|
||||
hueSaturation = "Hue/Saturation",
|
||||
colorBalance = "Color balance",
|
||||
photoFilter = "Photo filter",
|
||||
invertColors = "Invert colors",
|
||||
blackWhite = "Black and white",
|
||||
gaussianBlur = "Gaussian blur",
|
||||
hue = "Hue: ",
|
||||
saturation = "Saturation: ",
|
||||
brightness = "Brightness: ",
|
||||
filterColor = "Filter color",
|
||||
transparency = "Transparency: ",
|
||||
force = "Force"
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
path = "Путь: ",
|
||||
save = "Сохранить",
|
||||
saveAs = "Сохранить как",
|
||||
ok = "Ok",
|
||||
cancel = "Отмена",
|
||||
fileName = "Имя файла",
|
||||
newPicture = "Новое изображение",
|
||||
@ -35,7 +36,7 @@
|
||||
"F - символы брайля",
|
||||
" ",
|
||||
"X - поменять цвета",
|
||||
"D - убрать цвет в изображении",
|
||||
"D - сбросить цвета рисованияы",
|
||||
},
|
||||
tool1 = "Инструмент выделения способен выделять отдельные участки изображения и делать с ними определенные действия. Зелеными точками обозначается начало и конец выделения (полезно для растеризации линии)",
|
||||
fill = "Залить",
|
||||
@ -50,7 +51,7 @@
|
||||
tool4 = "Инструмент пипетка позволяет получать первичный и вторичный цвет выбранного пикселя. Вы можете выбрать, какие цвета захватывать.",
|
||||
pickBack = "Захватывать фон:",
|
||||
pickFor = "Захватывать перед:",
|
||||
tool5 = "Классический инструмент кисть прозволяет рисовать на изображении с указанным радиусом и прозрачностью. Вы можете выбрать, что будет рисоваться. Также можно выбрать символ, которым будет рисовать кисть, иначе она будет рисовать пустым символом.",
|
||||
tool5 = "Классический инструмент кисть позволяет рисовать на изображении с указанным радиусом и прозрачностью. Вы можете выбрать, что будет рисоваться. Также можно выбрать символ, которым будет рисовать кисть, иначе она будет рисовать пустым символом.",
|
||||
drawBack = "Рисовать на фоне:",
|
||||
drawFor = "Рисовать на пер.:",
|
||||
drawAlpha = "Изменять прозр.:",
|
||||
@ -65,5 +66,24 @@
|
||||
eraseSym = "Стирать символ:",
|
||||
tool7 = "Инструмент текста позволяет писать текст с указанным первичным и вторичным цветом прямо на изображении! Время сказать всем \"твоя мама гей\" <3",
|
||||
tool8 = "Инструмент заливка позволяет автоматически заполнять зоны с указанным первичным и вторичным цветом, как это делает Paint. О боже, а где вся оперативка...?",
|
||||
tool9 = "Утилита Брайля позволяет рисовать пиксели с помощью шрифта Брайля. Выберите мини-пиксели в свойствах, настройте прозрачность и поехали!"
|
||||
}
|
||||
tool9 = "Инструмент Брайля позволяет рисовать пиксели с помощью шрифта Брайля. Выберите мини-пиксели в свойствах, настройте прозрачность и поехали!",
|
||||
image = "Изображение",
|
||||
edit = "Редактировать",
|
||||
rotate90 = "Повернуть на 90 градусов",
|
||||
rotate180 = "Повернуть на 180 градусов",
|
||||
rotate270 = "Повернуть на 270 градусов",
|
||||
flipVertical = "Отразить по вертикали",
|
||||
flipHorizontal = "Отразить по горизонтали",
|
||||
hueSaturation = "Тон/Насыщенность",
|
||||
colorBalance = "Цветовой баланс",
|
||||
photoFilter = "Фотофильтр",
|
||||
invertColors = "Инвертировать цвета",
|
||||
blackWhite = "Черно-белый фильтр",
|
||||
gaussianBlur = "Размытие по Гауссу",
|
||||
hue = "Тон: ",
|
||||
saturation = "Насыщенность: ",
|
||||
brightness = "Яркость: ",
|
||||
filterColor = "Цвет фильтра",
|
||||
transparency = "Прозрачность: ",
|
||||
force = "Сила: "
|
||||
}
|
||||
|
||||
@ -134,7 +134,6 @@ window.sidebarLayout.eventHandler = function(workspace, object, e1, e2, e3, e4,
|
||||
end
|
||||
|
||||
window.sidebarLayout:setMargin(1, 1, h, v)
|
||||
workspace:draw()
|
||||
end
|
||||
end
|
||||
|
||||
@ -146,7 +145,6 @@ for i = 1, #config.recentColors do
|
||||
local button = recentColorsContainer:addChild(GUI.button(x, y, 2, 1, 0x0, 0x0, 0x0, 0x0, " "))
|
||||
button.onTouch = function()
|
||||
window.primaryColorSelector.color = config.recentColors[i]
|
||||
workspace:draw()
|
||||
end
|
||||
|
||||
x = x + 2
|
||||
@ -199,7 +197,6 @@ local function onToolTouch(index)
|
||||
aboutToolTextBox.height = #aboutToolTextBox.lines
|
||||
end
|
||||
|
||||
workspace:draw()
|
||||
end
|
||||
|
||||
local tools = filesystem.list(toolsPath)
|
||||
@ -277,7 +274,6 @@ end
|
||||
|
||||
local function swapColors()
|
||||
window.primaryColorSelector.color, window.secondaryColorSelector.color = window.secondaryColorSelector.color, window.primaryColorSelector.color
|
||||
workspace:draw()
|
||||
end
|
||||
|
||||
local function colorSelectorDraw(object)
|
||||
@ -292,7 +288,7 @@ window.secondaryColorSelector = window:addChild(GUI.colorSelector(3, 1, 5, 2, 0x
|
||||
window.primaryColorSelector = window:addChild(GUI.colorSelector(2, 1, 5, 2, 0x000000, " "))
|
||||
window.secondaryColorSelector.draw, window.primaryColorSelector.draw = colorSelectorDraw, colorSelectorDraw
|
||||
|
||||
window.swapColorsButton = window:addChild(GUI.button(1, 1, window.toolsList.width, 1, nil, 0x696969, nil, 0xA5A5A5, ">"))
|
||||
window.swapColorsButton = window:addChild(GUI.button(1, 1, window.toolsList.width, 1, nil, 0x696969, nil, 0xA5A5A5, " ←→"))
|
||||
window.swapColorsButton.onTouch = swapColors
|
||||
|
||||
local function setSavePath(path)
|
||||
@ -346,7 +342,6 @@ local function saveAs()
|
||||
|
||||
filesystemDialog.onSubmit = function(path)
|
||||
save(path)
|
||||
workspace:draw()
|
||||
end
|
||||
end
|
||||
|
||||
@ -365,6 +360,7 @@ end
|
||||
|
||||
local function new()
|
||||
local container = GUI.addBackgroundContainer(workspace, true, true, locale.newPicture)
|
||||
container.panel.eventHandler = nil
|
||||
|
||||
local layout = container.layout:addChild(GUI.layout(1, 1, 36, 3, 1, 1))
|
||||
layout:setDirection(1, 1, GUI.DIRECTION_HORIZONTAL)
|
||||
@ -378,23 +374,23 @@ local function new()
|
||||
layout:addChild(GUI.text(1, 1, 0x696969, " x "))
|
||||
local heightInput = addInput("", locale.height)
|
||||
widthInput.width, heightInput.width = 16, 17
|
||||
|
||||
container.panel.eventHandler = function(workspace, panel, e1)
|
||||
if e1 == "touch" then
|
||||
if
|
||||
widthInput.text:match("%d+") and
|
||||
heightInput.text:match("%d+")
|
||||
then
|
||||
newNoGUI(tonumber(widthInput.text), tonumber(heightInput.text), nil)
|
||||
window.image.reposition()
|
||||
end
|
||||
|
||||
container:remove()
|
||||
workspace:draw()
|
||||
|
||||
container.layout:addChild(GUI.button(1, 1, 30, 3, 0xFFFFFF, 0x555555, 0x880000, 0xFFFFFF, locale.ok)).onTouch = function()
|
||||
if
|
||||
widthInput.text:match("%d+") and
|
||||
heightInput.text:match("%d+")
|
||||
then
|
||||
newNoGUI(tonumber(widthInput.text), tonumber(heightInput.text), nil)
|
||||
window.image.reposition()
|
||||
end
|
||||
|
||||
container:remove()
|
||||
end
|
||||
|
||||
container.layout:addChild(GUI.button(1, 1, 30, 3, 0xFFFFFF, 0x555555, 0x880000, 0xFFFFFF, locale.cancel)).onTouch = function()
|
||||
container:remove()
|
||||
end
|
||||
|
||||
workspace:draw()
|
||||
end
|
||||
|
||||
local function open()
|
||||
@ -409,7 +405,6 @@ local function open()
|
||||
loadImage(path)
|
||||
|
||||
window.image.reposition()
|
||||
workspace:draw()
|
||||
end
|
||||
end
|
||||
|
||||
@ -484,9 +479,7 @@ fileItem:addItem(locale.new, false, "^N").onTouch = new
|
||||
|
||||
fileItem:addSeparator()
|
||||
|
||||
fileItem:addItem(locale.open, false, "^O").onTouch = function()
|
||||
open()
|
||||
end
|
||||
fileItem:addItem(locale.open, false, "^O").onTouch = open
|
||||
|
||||
local fileItemSubMenu = fileItem:addSubMenuItem(locale.openRecent, #config.recentFiles == 0)
|
||||
for i = 1, #config.recentFiles do
|
||||
@ -494,17 +487,23 @@ for i = 1, #config.recentFiles do
|
||||
loadImage(config.recentFiles[i])
|
||||
|
||||
window.image.reposition()
|
||||
workspace:draw()
|
||||
end
|
||||
end
|
||||
|
||||
fileItem:addItem(locale.openFromURL).onTouch = function()
|
||||
local container = GUI.addBackgroundContainer(workspace, true, true, locale.openFromURL)
|
||||
container.panel.eventHandler = nil
|
||||
|
||||
local input = container.layout:addChild(GUI.input(1, 1, 36, 3, 0xE1E1E1, 0x696969, 0x969696, 0xE1E1E1, 0x2D2D2D, "", "http://example.com/test.pic"))
|
||||
input.onInputFinished = function()
|
||||
local okBut = container.layout:addChild(GUI.button(1, 1, 30, 3, 0xFFFFFF, 0x555555, 0x880000, 0xFFFFFF, locale.ok))
|
||||
local cancelBut = container.layout:addChild(GUI.button(1, 1, 30, 3, 0xFFFFFF, 0x555555, 0x880000, 0xFFFFFF, locale.cancel))
|
||||
|
||||
okBut.onTouch = function()
|
||||
if #input.text > 0 then
|
||||
input:remove()
|
||||
okBut:remove()
|
||||
cancelBut:remove()
|
||||
|
||||
container.layout:addChild(GUI.label(1, 1, container.width, 1, 0x969696, locale.downloading):setAlignment(GUI.ALIGNMENT_HORIZONTAL_CENTER, GUI.ALIGNMENT_VERTICAL_TOP))
|
||||
workspace:draw()
|
||||
|
||||
@ -523,11 +522,14 @@ fileItem:addItem(locale.openFromURL).onTouch = function()
|
||||
GUI.alert(reason)
|
||||
end
|
||||
|
||||
workspace:draw()
|
||||
else
|
||||
container:remove()
|
||||
end
|
||||
end
|
||||
|
||||
workspace:draw()
|
||||
|
||||
cancelBut.onTouch = function()
|
||||
container:remove()
|
||||
end
|
||||
end
|
||||
|
||||
fileItem:addSeparator()
|
||||
@ -541,28 +543,163 @@ fileItem:addItem(locale.saveAs, false, "^⇧S").onTouch = saveAs
|
||||
|
||||
menu:addItem(locale.view).onTouch = function()
|
||||
local container = GUI.addBackgroundContainer(workspace, true, true, locale.view)
|
||||
container.panel.eventHandler = nil
|
||||
|
||||
local colorSelector1 = container.layout:addChild(GUI.colorSelector(1, 1, 36, 3, config.transparencyBackground, locale.transBack))
|
||||
local colorSelector2 = container.layout:addChild(GUI.colorSelector(1, 1, 36, 3, config.transparencyForeground, locale.transFor))
|
||||
|
||||
container.panel.eventHandler = function(workspace, object, e1)
|
||||
if e1 == "touch" then
|
||||
config.transparencyBackground, config.transparencyForeground = colorSelector1.color, colorSelector2.color
|
||||
|
||||
container.layout:addChild(GUI.button(1, 1, 30, 3, 0xFFFFFF, 0x555555, 0x880000, 0xFFFFFF, locale.ok)).onTouch = function()
|
||||
config.transparencyBackground, config.transparencyForeground = colorSelector1.color, colorSelector2.color
|
||||
|
||||
container:remove()
|
||||
workspace:draw()
|
||||
saveConfig()
|
||||
end
|
||||
container:remove()
|
||||
saveConfig()
|
||||
end
|
||||
|
||||
container.layout:addChild(GUI.button(1, 1, 30, 3, 0xFFFFFF, 0x555555, 0x880000, 0xFFFFFF, locale.cancel)).onTouch = function()
|
||||
container:remove()
|
||||
end
|
||||
end
|
||||
|
||||
workspace:draw()
|
||||
local imageItem = menu:addContextMenuItem(locale.image)
|
||||
|
||||
imageItem:addItem(locale.flipVertical).onTouch = function()
|
||||
window.image.data = image.flipVertically(window.image.data)
|
||||
end
|
||||
|
||||
imageItem:addItem(locale.flipHorizontal).onTouch = function()
|
||||
window.image.data = image.flipHorizontally(window.image.data)
|
||||
end
|
||||
|
||||
imageItem:addSeparator()
|
||||
|
||||
imageItem:addItem(locale.rotate90).onTouch = function()
|
||||
window.image.data = image.rotate(window.image.data, 90)
|
||||
window.image.width = window.image.data[1]
|
||||
window.image.height = window.image.data[2]
|
||||
window.image.reposition()
|
||||
end
|
||||
|
||||
imageItem:addItem(locale.rotate180).onTouch = function()
|
||||
window.image.data = image.rotate(window.image.data, 180)
|
||||
window.image.width = window.image.data[1]
|
||||
window.image.height = window.image.data[2]
|
||||
window.image.reposition()
|
||||
end
|
||||
|
||||
imageItem:addItem(locale.rotate270).onTouch = function()
|
||||
window.image.data = image.rotate(window.image.data, 270)
|
||||
window.image.width = window.image.data[1]
|
||||
window.image.height = window.image.data[2]
|
||||
window.image.reposition()
|
||||
end
|
||||
|
||||
local editItem = menu:addContextMenuItem(locale.edit)
|
||||
|
||||
editItem:addItem(locale.hueSaturation).onTouch = function()
|
||||
local container = GUI.addBackgroundContainer(workspace, true, true, locale.hueSaturation)
|
||||
container.layout:setSpacing(1, 1, 2)
|
||||
container.panel.eventHandler = nil
|
||||
|
||||
local hue = container.layout:addChild(GUI.slider(1, 1, 50, 0x66DB80, 0x0, 0xFFFFFF, 0xAAAAAA, -360, 360, 0, true, locale.hue))
|
||||
local satur = container.layout:addChild(GUI.slider(1, 1, 50, 0x66DB80, 0x0, 0xFFFFFF, 0xAAAAAA, -100, 100, 0, true, locale.saturation))
|
||||
local bright = container.layout:addChild(GUI.slider(1, 1, 50, 0x66DB80, 0x0, 0xFFFFFF, 0xAAAAAA, -100, 100, 0, true, locale.brightness))
|
||||
hue.roundValues = true
|
||||
satur.roundValues = true
|
||||
bright.roundValues = true
|
||||
|
||||
local buttonsLay = container.layout:addChild(GUI.layout(1, 1, 30, 7, 1, 1))
|
||||
|
||||
buttonsLay:addChild(GUI.button(1, 1, 30, 3, 0xFFFFFF, 0x555555, 0x880000, 0xFFFFFF, locale.ok)).onTouch = function()
|
||||
window.image.data = image.hueSaturationBrightness(window.image.data, hue.value, satur.value/100, bright.value/100)
|
||||
container:remove()
|
||||
end
|
||||
|
||||
buttonsLay:addChild(GUI.button(1, 1, 30, 3, 0xFFFFFF, 0x555555, 0x880000, 0xFFFFFF, locale.cancel)).onTouch = function()
|
||||
container:remove()
|
||||
end
|
||||
end
|
||||
|
||||
editItem:addItem(locale.colorBalance).onTouch = function()
|
||||
local container = GUI.addBackgroundContainer(workspace, true, true, locale.colorBalance)
|
||||
container.layout:setSpacing(1, 1, 2)
|
||||
container.panel.eventHandler = nil
|
||||
|
||||
local r = container.layout:addChild(GUI.slider(1, 1, 50, 0x66DB80, 0x0, 0xFF0000, 0xAAAAAA, -255, 255, 0, true, "R: "))
|
||||
local g = container.layout:addChild(GUI.slider(1, 1, 50, 0x66DB80, 0x0, 0x00FF00, 0xAAAAAA, -255, 255, 0, true, "G: "))
|
||||
local b = container.layout:addChild(GUI.slider(1, 1, 50, 0x66DB80, 0x0, 0x0000FF, 0xAAAAAA, -255, 255, 0, true, "B: "))
|
||||
r.roundValues = true
|
||||
g.roundValues = true
|
||||
b.roundValues = true
|
||||
|
||||
local buttonsLay = container.layout:addChild(GUI.layout(1, 1, 30, 7, 1, 1))
|
||||
|
||||
buttonsLay:addChild(GUI.button(1, 1, 30, 3, 0xFFFFFF, 0x555555, 0x880000, 0xFFFFFF, locale.ok)).onTouch = function()
|
||||
window.image.data = image.colorBalance(window.image.data, math.floor(r.value), math.floor(g.value), math.floor(b.value))
|
||||
container:remove()
|
||||
end
|
||||
|
||||
buttonsLay:addChild(GUI.button(1, 1, 30, 3, 0xFFFFFF, 0x555555, 0x880000, 0xFFFFFF, locale.cancel)).onTouch = function()
|
||||
container:remove()
|
||||
end
|
||||
end
|
||||
|
||||
editItem:addItem(locale.photoFilter).onTouch = function()
|
||||
local container = GUI.addBackgroundContainer(workspace, true, true, locale.photoFilter)
|
||||
container.layout:setSpacing(1, 1, 2)
|
||||
container.panel.eventHandler = nil
|
||||
|
||||
local filterColor = container.layout:addChild(GUI.colorSelector(1, 1, 30, 3, 0x333333, locale.filterColor))
|
||||
local transparency = container.layout:addChild(GUI.slider(1, 1, 50, 0x66DB80, 0x0, 0xFFFFFF, 0xAAAAAA, 0, 1, 0.5, true, locale.transparency))
|
||||
|
||||
local buttonsLay = container.layout:addChild(GUI.layout(1, 1, 30, 7, 1, 1))
|
||||
|
||||
buttonsLay:addChild(GUI.button(1, 1, 30, 3, 0xFFFFFF, 0x555555, 0x880000, 0xFFFFFF, locale.ok)).onTouch = function()
|
||||
window.image.data = image.photoFilter(window.image.data, filterColor.color, transparency.value)
|
||||
container:remove()
|
||||
end
|
||||
|
||||
buttonsLay:addChild(GUI.button(1, 1, 30, 3, 0xFFFFFF, 0x555555, 0x880000, 0xFFFFFF, locale.cancel)).onTouch = function()
|
||||
container:remove()
|
||||
end
|
||||
end
|
||||
|
||||
editItem:addSeparator()
|
||||
|
||||
editItem:addItem(locale.invertColors).onTouch = function()
|
||||
window.image.data = image.invert(window.image.data)
|
||||
end
|
||||
|
||||
editItem:addItem(locale.blackWhite).onTouch = function()
|
||||
window.image.data = image.blackAndWhite(window.image.data)
|
||||
end
|
||||
|
||||
editItem:addSeparator()
|
||||
|
||||
editItem:addItem(locale.gaussianBlur).onTouch = function()
|
||||
local container = GUI.addBackgroundContainer(workspace, true, true, locale.gaussianBlur)
|
||||
container.layout:setSpacing(1, 1, 2)
|
||||
container.panel.eventHandler = nil
|
||||
|
||||
local radius = container.layout:addChild(GUI.slider(1, 1, 50, 0x66DB80, 0x0, 0xFFFFFF, 0xAAAAAA, 0, 5, 2.5, true, locale.radius))
|
||||
local force = container.layout:addChild(GUI.slider(1, 1, 50, 0x66DB80, 0x0, 0xFFFFFF, 0xAAAAAA, 0, 1, 0.5, true, locale.force))
|
||||
radius.roundValues = true
|
||||
|
||||
local buttonsLay = container.layout:addChild(GUI.layout(1, 1, 30, 7, 1, 1))
|
||||
|
||||
buttonsLay:addChild(GUI.button(1, 1, 30, 3, 0xFFFFFF, 0x555555, 0x880000, 0xFFFFFF, locale.ok)).onTouch = function()
|
||||
window.image.data = image.gaussianBlur(window.image.data, math.floor(radius.value), force.value)
|
||||
container:remove()
|
||||
end
|
||||
|
||||
buttonsLay:addChild(GUI.button(1, 1, 30, 3, 0xFFFFFF, 0x555555, 0x880000, 0xFFFFFF, locale.cancel)).onTouch = function()
|
||||
container:remove()
|
||||
end
|
||||
end
|
||||
|
||||
menu:addItem(locale.hotkeys).onTouch = function()
|
||||
local container = GUI.addBackgroundContainer(workspace, true, true, locale.hotkeys)
|
||||
|
||||
container.layout:addChild(GUI.textBox(1, 1, 36, 1, nil, 0x969696, locale.hotkeysText, 1, 0, 0, true, true)).eventHandler = nil
|
||||
workspace:draw()
|
||||
end
|
||||
|
||||
window.currentToolOverlay = window:addChild(GUI.container(1, 1, 1, 1))
|
||||
|
||||
@ -456,6 +456,161 @@ function image.blend(picture, blendColor, transparency)
|
||||
return newPicture
|
||||
end
|
||||
|
||||
function image.rotate(picture, angle)
|
||||
local function copyPixel(newPic, oldPic, index)
|
||||
table.insert(newPic, oldPic[index])
|
||||
table.insert(newPic, oldPic[index + 1])
|
||||
table.insert(newPic, oldPic[index + 2])
|
||||
table.insert(newPic, oldPic[index + 3])
|
||||
end
|
||||
|
||||
if angle == 90 then
|
||||
local newPicture = {picture[2], picture[1]}
|
||||
for i = 1, picture[2] do
|
||||
for j = picture[1], 1, -1 do
|
||||
local index = image.getIndex(i, j, picture[2])
|
||||
copyPixel(newPicture, picture, index)
|
||||
end
|
||||
end
|
||||
return newPicture
|
||||
elseif angle == 180 then
|
||||
local newPicture = {picture[1], picture[2]}
|
||||
for j = picture[1], 1, -1 do
|
||||
for i = picture[2], 1, -1 do
|
||||
local index = image.getIndex(i, j, picture[2])
|
||||
copyPixel(newPicture, picture, index)
|
||||
end
|
||||
end
|
||||
return newPicture
|
||||
elseif angle == 270 then
|
||||
local newPicture = {picture[2], picture[1]}
|
||||
for i = picture[2], 1, -1 do
|
||||
for j = 1, picture[1] do
|
||||
local index = image.getIndex(i, j, picture[2])
|
||||
copyPixel(newPicture, picture, index)
|
||||
end
|
||||
end
|
||||
return newPicture
|
||||
else
|
||||
error("Can't rotate image: angle must be 90, 180 or 270 degrees.")
|
||||
end
|
||||
end
|
||||
|
||||
function image.gaussianBlur(picture, radius, force)
|
||||
local function createConvolutionMatrix(maximumValue, matrixSize)
|
||||
local delta = maximumValue / matrixSize
|
||||
local matrix = {}
|
||||
for y = 1, matrixSize do
|
||||
for x = 1, matrixSize do
|
||||
local value = ((x - 1) * delta + (y - 1) * delta) / 2
|
||||
matrix[y] = matrix[y] or {}
|
||||
matrix[y][x] = value
|
||||
end
|
||||
end
|
||||
return matrix
|
||||
end
|
||||
|
||||
local function spreadPixelToSpecifiedCoordinates(picture, xCoordinate, yCoordinate, matrixValue, startBackground, startForeground, startAlpha, startSymbol)
|
||||
local matrixBackground, matrixForeground, matrixAlpha, matrixSymbol = image.get(picture, xCoordinate, yCoordinate)
|
||||
|
||||
if matrixBackground and matrixForeground then
|
||||
local newBackground = color.blend(startBackground, matrixBackground, matrixValue)
|
||||
local newForeground = matrixSymbol == " " and newBackground or color.blend(startForeground, matrixForeground, matrixValue)
|
||||
|
||||
image.set(picture, xCoordinate, yCoordinate, newBackground, newForeground, 0x00, matrixSymbol)
|
||||
end
|
||||
end
|
||||
|
||||
local function spreadColorToOtherPixels(picture, xStart, yStart, matrix)
|
||||
local startBackground, startForeground, startAlpha, startSymbol = image.get(picture, xStart, yStart)
|
||||
local xCoordinate, yCoordinate
|
||||
for yMatrix = 2, #matrix do
|
||||
for xMatrix = 2, #matrix[yMatrix] do
|
||||
xCoordinate, yCoordinate = xStart - xMatrix + 1, yStart - yMatrix + 1
|
||||
spreadPixelToSpecifiedCoordinates(picture, xCoordinate, yCoordinate, matrix[yMatrix][xMatrix], startBackground, startForeground, startAlpha, startSymbol)
|
||||
xCoordinate, yCoordinate = xStart + xMatrix - 1, yStart + yMatrix - 1
|
||||
spreadPixelToSpecifiedCoordinates(picture, xCoordinate, yCoordinate, matrix[yMatrix][xMatrix], startBackground, startForeground, startAlpha, startSymbol)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local matrix = createConvolutionMatrix(force or 0x55, radius)
|
||||
for y = 1, picture[2] do
|
||||
for x = 1, picture[1] do
|
||||
spreadColorToOtherPixels(picture, x, y, matrix)
|
||||
end
|
||||
end
|
||||
return picture
|
||||
end
|
||||
|
||||
function image.hueSaturationBrightness(picture, hue, saturation, brightness)
|
||||
local function calculateBrightnessChanges(colr)
|
||||
local h, s, b = color.integerToHSB(colr)
|
||||
b = b + brightness; if b < 0 then b = 0 elseif b > 1 then b = 1 end
|
||||
s = s + saturation; if s < 0 then s = 0 elseif s > 1 then s = 1 end
|
||||
h = h + hue; if h < 0 then h = 0 elseif h > 360 then h = 360 end
|
||||
return color.HSBToInteger(h, s, b)
|
||||
end
|
||||
|
||||
for i = 3, #picture, 4 do
|
||||
picture[i] = calculateBrightnessChanges(picture[i])
|
||||
picture[i + 1] = calculateBrightnessChanges(picture[i + 1])
|
||||
end
|
||||
|
||||
return picture
|
||||
end
|
||||
|
||||
function image.hue(picture, hue)
|
||||
return image.hueSaturationBrightness(picture, hue, 0, 0)
|
||||
end
|
||||
|
||||
function image.saturation(picture, saturation)
|
||||
return image.hueSaturationBrightness(picture, 0, saturation, 0)
|
||||
end
|
||||
|
||||
function image.brightness(picture, brightness)
|
||||
return image.hueSaturationBrightness(picture, 0, 0, brightness)
|
||||
end
|
||||
|
||||
function image.blackAndWhite(picture)
|
||||
return image.hueSaturationBrightness(picture, 0, -1, 0)
|
||||
end
|
||||
|
||||
function image.colorBalance(picture, r, g, b)
|
||||
local function calculateRGBChanges(colr)
|
||||
local rr, gg, bb = color.integerToRGB(colr)
|
||||
rr = rr + r; gg = gg + g; bb = bb + b
|
||||
if rr < 0 then rr = 0 elseif rr > 255 then rr = 255 end
|
||||
if gg < 0 then gg = 0 elseif gg > 255 then gg = 255 end
|
||||
if bb < 0 then bb = 0 elseif bb > 255 then bb = 255 end
|
||||
return color.RGBToInteger(rr, gg, bb)
|
||||
end
|
||||
|
||||
for i = 3, #picture, 4 do
|
||||
picture[i] = calculateRGBChanges(picture[i])
|
||||
picture[i + 1] = calculateRGBChanges(picture[i + 1])
|
||||
end
|
||||
|
||||
return picture
|
||||
end
|
||||
|
||||
function image.invert(picture)
|
||||
for i = 3, #picture, 4 do
|
||||
picture[i] = 0xffffff - picture[i]
|
||||
picture[i + 1] = 0xffffff - picture[i + 1]
|
||||
end
|
||||
return picture
|
||||
end
|
||||
|
||||
function image.photoFilter(picture, colr, transparency)
|
||||
if transparency < 0 then transparency = 0 elseif transparency > 1 then transparency = 1 end
|
||||
for i = 3, #picture, 4 do
|
||||
picture[i] = color.blend(picture[i], colr, transparency)
|
||||
picture[i + 1] = color.blend(picture[i + 1], colr, transparency)
|
||||
end
|
||||
return picture
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
return image
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user