ECS 1 903 Опубликовано: 12 января, 2016 (изменено) Хочу представить вам большую библиотеку, предназначенную для работы с изображениями, созданными в нашем Фотошопе. С ее помощью можно манипулировать графикой воистину волшебным образом: изображения можно обрезать, расширять, поворачивать, отражать, инвертировать, изменять их яркость, цветовой тон, насыщенность и добавлять фотофильтры. Разрабатывали мы ее примерно год, содержит она более 1000 строк кода и удовлетворяет практически всем наши требованиям к хорошей графике в OpenComputers, если, конечно, местную графику вообще можно назвать хорошей. Начало работы Прежде всего вам потребуются два файла. Первый обеспечивает основные операции над цветом, позволяет конвертировать цвета из одной схемы в другую, а также сжимать цвета без потери качества. Второй же является самой библиотекой image и дает нам полную свободу творчества. wget https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/lib/colorlib.lua lib/colorlib.lua -f wget https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/lib/image.lua lib/image.lua -f После загрузки библиотек вы можете подключить image и начинать с ней работать. Далее мы рассмотрим различные методы, с помощью которых мы сможем манипулировать изображениями. Под описанием каждого метода будет картинка и код, демонстрирующие суть работы метода, так что проблем с пониманием возникнуть не должно. local image = require("image") Структура изображений (для общего развития) Для начала я расскажу вам, как реализовано хранение изображений в оперативной памяти компьютера. Итак, каждое изображение у нас - это обычный массив. Мы специально используем одномерный массив для экономии оперативной памяти, а при отрисовке библиотека сама получает координаты x и y по особым формулам, что совсем не сказывается на производительности. В данном массиве чередуются цвет фона, цвет текста, альфа-канал и символ. Это что касается оперативной памяти. А теперь я покажу вам, каким образом данные о пикселях хранятся в файлах .pic на жестком диске, используя различные методы кодировки (0, 1, 2 или 3). Для наглядности мы будем открывать один и тот же файл "Love.pic", демонстрирующий нашу любовь к моду OpenComputers, сохраненный с различными методами кодировки. К примеру, при кодировке 0 изображение с сердечком хранится в следующем виде: Видно, что это крайне неоптимизированный метод, никак не сжимающий картинку, все данные хранятся в сыром виде, отсюда и название метода. Он полезен для дебага, когда надо вручную подправить данные. Также видно, что в начале файла у нас 4 байта отводится под сигнатуру (таким образом мы отличаем наш формат .pic от всякой ерунды), а также 1 байт на метод кодирования. Далее рассмотрим метод кодировки 1. Мы довольно долго пользовались им, он использует простейшее "сжатие", когда данные записываются не в виде символов, а в виде последовательности байт. У него есть один недостаток: в файле постоянно повторяются схожие данные, к примеру, если наше изображение имеет размеры 10х10 пикселей и черный фон, то данные о фоне повторятся в файле 100 раз. Это неправильно. А теперь давайте посмотрим на метод кодирования 2, он работает схожим образом, однако при нем в файлах отсутствуют повторяющиеся блоки. То есть, опять таки, если у нас в изображении цвет фона только черный, от в файл данные о черном фоне запишутся лишь один раз. Видно, что размер файла уже существенно уменьшился. Однако для записи цветов тут используются 3 байта (т.е. белый будет 0xFFFFFF), в то время как палитра OpenComputers поддерживает лишь 256 возможных оттенков. Отсюда вывод, что мы неэкономно храним данные. Если взглянуть на метод кодировки 3, то сразу видно, что размер файла стал еще меньше. При этом на цвет используется лишь 1 байт (т.е. белый будет 0xFF). Это крайне оптимизированный формат картинок, вылизанный, что называется, дочиста. Методы работы с файлами изображений (загрузка, отрисовка, сохранение) image.load( string путь ): table изображение Загружает существующий файл .pic из указанного пути и возвращает изображение в виде массива. local myPicture = image.load("MineOS/System/OS/Icons/Love.pic") image.save( string путь, table изображение [, int метод кодирования] ) Сохраняет существующий массив изображения в файл по указанному пути. Формат файла должен быть .pic. Опционально можно указать метод кодирования от 0 до 3, однако крайне рекомендуется использовать 3 для экономии места на диске. image.save("copyOfMyPicture.pic", myPicture) image.draw( int x, int y, table изображение ) Рисует загруженное ранее изображение по указанным координатам. image.draw(8, 4, myPicture) Методы трансформирования изображений (вращение, отражение, обрезание и т.п.) image.expand( table изображение, string направление, int количество пикселей[, int цвет фона, int цвет текста, int прозрачность, string символ] ): table картинка Расширяет указанную картинку в указанном направлении (fromRight, fromLeft, fromTop, fromBottom), создавая при этом пустые белые пиксели. Если указаны опциональные аргументы, то вместо пустых пикселей могут быть вполне конкретные значения. image.draw(8, 4, myPicture) myPicture = image.expand(myPicture, "fromRight", 10) image.draw(53, 4, myPicture) image.crop( table изображение, string направление, int количество пикселей ): table изображение Обрезает указанную картинку в указанном направлении (fromRight, fromLeft, fromTop, fromBottom), удаляя лишние пиксели. image.draw(8, 4, myPicture) myPicture = image.crop(myPicture, "fromRight", 10) image.draw(53, 4, myPicture) image.rotate( table изображение, int угол ): table изображение Поворачивает указанную картинку на указанный угол. Угол может иметь значение 90, 180 и 270 градусов. image.draw(8, 4, myPicture) myPicture = image.rotate(myPicture, 90) image.draw(53, 4, myPicture) image.flipVertical( table изображение): table изображение Отражает указанную картинку по вертикали. image.draw(8, 4, myPicture) myPicture = image.flipVertical(myPicture) image.draw(53, 4, myPicture) image.flipHorizontal( table изображение): table изображение Отражает указанную картинку по горизонтали. image.draw(8, 4, myPicture) myPicture = image.flipHorizontal(myPicture) image.draw(53, 4, myPicture) Методы работы с цветом (яркость, насыщенность, тон и т.п.) image.hueSaturationBrightness( table изображение, int тон, int насыщенность, int яркость ): table изображение Корректирует цветовой тон, насыщенность и яркость указанной картинки. Значения аргументов могут быть отрицательными для уменьшения параметра и положительными для его увеличения. Если значение, к примеру, насыщенности менять не требуется, просто указывайте 0. Для удобства вы можете использовать следующие сокращения: image.hue( table изображение, int тон ): table изображение image.saturation( table изображение, int насыщенность ): table изображение image.brightness( table изображение, int яркость ): table изображение image.blackAndWhite( table изображение ): table изображение image.draw(8, 4, myPicture) --Изменяем цветовой тон к красному, уменьшаем яркость, не изменяя насыщенность myPicture = image.hueSaturationBrightness(myPicture, 200, 0, -10 ) image.draw(53, 4, myPicture) image.colorBalance( table изображение, int красный, int зеленый, int синий ): table изображение Корректирует цветовые каналы указанной картинки. Аргументы цветовых каналов могут принимать как отрицательные значения для уменьшения интенсивности канала, так и положительные для увеличения. image.draw(8, 4, myPicture) --Делаем изображение "зеленее" myPicture = image.colorBalance(myPicture, 0, 255, 0) image.draw(53, 4, myPicture) image.invert( table изображение ): table изображение Инвертирует цвета в указанной картинке. image.draw(8, 4, myPicture) myPicture = image.invert(myPicture) image.draw(53, 4, myPicture) image.photoFilter( table изображение, int цвет, int прозрачность ): table изображение Накладывает на указанное изображение фотофильтр с указанной прозрачностью. Прозрачность может быть от 0 до 255. image.draw(8, 4, myPicture) --Накладываем сиреневый фотофильтр с прозрачностью 80 myPicture = image.photoFilter(myPicture, 0xFF00FF, 80) image.draw(53, 4, myPicture) Изменено 23 марта, 2016 пользователем ECS 9 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
SergOmarov 34 Опубликовано: 16 января, 2016 Вынес функционал фотошопа в либу? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
ECS Автор темы 1 903 Опубликовано: 16 января, 2016 Вынес функционал фотошопа в либу? Тут функционала раза в 4 больше, чем в фотошопе, плюс, сам фотошоп всегда юзал функции из этой либы, являясь как бы графической оболочкой к либе. Хотел на днях перекодить ФШ с нуля, добавить поддержку двойного буфера, слоев, истории - поэтому и интегрировал все функции в либу image. Ну, и выложил ее сюда, чего добру пропадать. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах