Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / Посоветуйте конвертер Jpeg/PNG в PixelArt, или матем. алгоритм конвертации..

Посоветуйте конвертер Jpeg/PNG в PixelArt, или матем. алгоритм конвертации..

Страницы: 1 2 Следующая »
joubПостоялецwww12 мар. 201821:58#0
Всем дорого дня!
Посоветуйте конвертер Jpeg/PNG в PixelArt, или матем. алгоритм конвертации, хочу реализовать в игре возможность вставки реальных фото объектов, но так как игра на основе PixelArt графики - то необходимо перегнать эти фото в графику подходящую для самой игры ))
Нашел пару примеров для фотошопа, но это немного не то, хочу реализовать сам алгоритм что-бы пользователе сами могли это сделать )))
ВасянУчастникwww12 мар. 201822:58#1
joub
Может тебе надо просто количество цветов и разрешение уменьшить?

С цветом, ну как вариант, представить, что будет, например, 64 цвета в итоговом изображении.
Формула перевода каждого пикселя:
pixelConverted = (pixel24bit / 0x40000) * 0x40000;

Короче, делим весь диапазон значений цвета на 64 части и цвет каждого пикселя обрезаем до значения, кратного 1/64 максимального 24-битного числа. В формуле выше тип данных int. Делить и умножать на одно и то же надо, чтобы выкинуть остаток. Вероятно, в math.h для этого есть отдельная функция, но такой вариант мне первым пришёл в голову. 0x40000 - 1/64-я от максимального 24-битного значения.

С уменьщением разрешения я бы так же сделал. Оставил строки и пиксели в строках, кратные какому-то числу.

Update:
Ниже Daniil Petrov меня поправил.

Правка: 13 мар. 2018 17:45

Daniil PetrovПостоялецwww13 мар. 20180:43#2
Васян
> Формула перевода каждого пикселя:
> pixelConverted = (pixel24bit / 0x40000) * 0x40000;
А почему ты смешал цвета RGB в кучу :))) тут для каждого цвета нужно делать pixelConverted = (pixel / 4) * 4;
256 / 64 = 4 :)

Правка: 13 мар. 2018 0:44

joubПостоялецwww13 мар. 20189:10#3
Вот пример с фотошопом, сперва идет работа с цветам, после - изменение размера...

https://www.shutterstock.com/blog/how-to-turn-any-photograph-into… ith-photoshop

на счет 64-х цветов... это много, мне желательно загнать все в 8-16  ))) , в общем нужно набросать код конвертера, и посмотреть что с этого получится..

ryzedПостоялецwww13 мар. 201810:32#4
MikleМодераторwww13 мар. 201812:04#5
joub
Я когда-то показывал фильтр "Линогравюра".
Общий смысл:
1. Преобразуем картинку в GrayScale.
2. Блурим с радиусами "мин" и "макс".
3. Вычитаем первый результат из второго.
4. Сравниваем попиксельно с величиной "смещение", если меньше - чёрный цвет, больше - белый.

Для пикселизации можно первый пункт убрать, а в п.4 сравнивать не с одним, а с несколькими смещениями покомпонентно R, G и B, потом уменьшить разрешение.

ВасянУчастникwww13 мар. 201817:43#6
Daniil Petrov
> А почему ты смешал цвета RGB в кучу :))) тут для каждого цвета нужно делать
> pixelConverted = (pixel / 4) * 4;
> 256 / 64 = 4 :)
Младшие байты с зелёным и синим улетят с остатком от деления? Да, об этом я не подумал. Ну, я всё-равно сократил палитру до 64-х цветов, лол.

Правка: 13 мар. 2018 17:48

joubПостоялецwww15 мар. 201823:43#7
RGB
R >>>=4;  // сдвигаем с обрезкой хвоста в право
R<<=4;    // и обратно
 private void imgeRead(File file) throws IOException {
        int ii = 4;
        BufferedImage image = ImageIO.read(file);

        int scaledHeight = 100;
        int scaledWidth = image.getWidth() * 100 / image.getHeight();
        BufferedImage scaled = new BufferedImage(scaledWidth, scaledHeight, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = scaled.createGraphics();
        g.drawImage(image, 0, 0, scaledWidth, scaledHeight, null);
        g.dispose();

        BufferedImage output = new BufferedImage(scaled.getWidth(), scaled.getHeight(), BufferedImage.TYPE_INT_ARGB);
        for (int i = 0; i < scaled.getHeight(); i++) {
            for (int j = 0; j < scaled.getWidth(); j++) {
                int color = scaled.getRGB(j, i);
                int A = (color >> 24) & 0xff;
                int R = (color >> 16) & 0xff;
                int G = (color >> 8) & 0xff;
                int B = (color) & 0xff;
                if (A == 255) {
                    R >>>= ii;
                    R <<= ii;
                    G >>>= ii;
                    G <<= ii;
                    B >>>= ii;
                    B <<= ii;
                } else {
                    R = G = B = A = 255;
                }
                output.setRGB(j, i, new Color(R, G, B, A).getRGB());
            }
        }
        File cDir = new File(path + File.separator + ASSETS);
        File outputfile = new File(cDir + File.separator + file.getName() + "_.png");
        ImageIO.write(output, "png", outputfile);
    }

вот как-то так... кусочек конвертора на Java...

youtubeПостоялецwww20 мар. 20186:52#8
joub
> R >>>=4;  // сдвигаем с обрезкой хвоста в право
> R<<=4;    // и обратно
R &= 0xf0; //?
Или
R = (color >> 16) & 0xf0;
...
?

Правка: 20 мар. 2018 6:53

joubПостоялецwww20 мар. 201810:57#9
youtube
> R &= 0xf0; //?
> Или
> R = (color >> 16) & 0xf0;

тогда уже лучше
color &= 0xFFF0F0F0;

но суть идеи обрезать последние 4 бита от каждого цвета, не затронув прозрачность.

kostik1337Постоялецwww22 мар. 201818:09#10
joub
Imagemagick? Он умеет переводить в индексированные цвета (даже с dithering'ом) и даунскейлить, примерно вот так:
convert in.png -colors 8 -resize 64x64 out.png
joubПостоялецwww22 мар. 201818:13#11
kostik1337
> Imagemagick? Он умеет переводить в индексированные цвета (даже с dithering'ом)
> и даунскейлить, примерно вот так:
> convert in.png -colors 8 -resize 64x64 out.png

спс, задача не найти утилиту - а написать свой код по переводу. так как это часть приложения.

kostik1337Постоялецwww22 мар. 201818:26#12
joub
Вообще, imagemagick это библиотека, так что можешь просто подключить его к своему проекту и вызывать программно (для джавы есть биндинги).
Если так хочется написать велосипед - исходники открыты, можешь подсмотреть там реализацию, или можешь попробовать выдрать из либы только нужный кусок
CiaphasПостоялецwww10 сен. 20188:37#13
Один прием приходит в голову:
В фоторедакторах при масштабировании картинки предлагают использовать разные фильтры.
Опишу способ, который я использовал с ACDSee: при увеличении картинки вдвое нужно использовать фильтр Box — он сохраняет прямые линии.
Это приведет к тому, что результирующая картинка будет состоять из однотонных квадратов 2х2 пиксела.
Таким образом можно сначала уменьшать вдвое картинку, а потом восстанавливать вышеописанным способом.
Это даст пикселизированное изображение. Может получиться похоже на пиксел-арт.

Если писать свой код, то то же самое будет выглядеть так:
при проходе по картинке каждая группа из 2х2 пикселей заменяется одноцветной группой, где RGB результирующего цвета
равно среднему арифметическому цветов изначальных пикселей группы.

joubПостоялецwww10 сен. 20188:50#14
спасибо, но не немножко не о том. суть проблемы уменьшения количества цветов (палитры). уж очень много оттенков выходит...
Страницы: 1 2 Следующая »

/ Форум / Программирование игр / 2D графика и изометрия

2001—2018 © GameDev.ru — Разработка игр