Кстати, о Спектруме. А в чем преимущество к известным утилитам bp2scr и другим?
Вид для печати
Кстати, о Спектруме. А в чем преимущество к известным утилитам bp2scr и другим?
Похожая утилита, опенсорс, Windows/Linux/macOS: https://github.com/jarikomppa/img2spec
Может лучше ее допиливать?
Какой-нибудь dithering планируется? Алгоритм Флойда-Стейнберга или сеткой (не знаю точно как он называется) были бы уместны.
- - - Добавлено - - -
Готовые черно-белые картинки плохо получаются, некоторые целые знакоместа выходят полностью черные. И если в знакоместе есть черные точки, то яркость знакоместа получается обычная, а не повышенная.
Он вроде бы где-то писал, что у него там какие-то проблемы, завал. В общем, ему временно не до хобби.
Не подскажите где почитать за алгоритмы конвертации любой цветной картинки в 2-х цветную (wbmp например) с % дизеринга ?
Upd:
https://m.habr.com/ru/post/326936/
У себя делал так:
И вспомогательные функцииКод:for (int y = 0; y < 192; y += 8) //цикл по высоте(по знакоместам)
for (int x = 0; x < 256; x += 8) //цикл по ширине(по знакоместам)
{
map<TColor,int> cmap; // создаём map в которой ключ - цвет, значение - количество пикселей данного цвета в знакоместе
for (int yy = 0; yy < 8; yy++)//цикл по пикселям знакоместа
for (int xx = 0; xx < 8; xx++)
{
TColor c = ColorMod(Canvas->Pixels[x+xx][y+yy]); // модификация цвета пикселя в отдельной функции
Canvas->Pixels[260+x+xx][y+yy] = c; // выведем преобразованную картинку рядом с оригиналом(цвета уже ZX, но не 2 цвета на знакоместа)
cmap[c]++; // увеличим счётчик данного цвета в мапе
}
map<TColor,int>::iterator it;
TColor ink = TColor(0);// цвет INK пока что чёрный
int ci = 0; // переменная для сравнения количества пикселей разных цветов
// найдём цвет, который в знакоместе встречается чаще всех, и сделаем INK
for (it = cmap.begin(); it != cmap.end(); it++) // пройдёмся по map с сохранёнными цветами
{
if (it->second > ci) //если количество пикселей данного цвета больше чем предыдущее сохранённое количество
{
ci = it->second; //сохраним наибольшее количество
ink = it->first; // сохраним сам цвет, который соответствует этому количеству
}
}
// удалим с мапы найденый цвет
cmap.erase(ink);
TColor paper = TColor(0);
int cp = 0;
// найдём второй цвет, который в знакоместе встречается чаще всех после INK, и сделаем его цветом PAPER
for (it = cmap.begin(); it != cmap.end(); it++)
{
if (it->second > cp)
{
cp = it->second;
paper = it->first;
}
}
// все остальные цвета, отличные от PAPER и INK, будем выводить либо тем, либо вторым цветом.
bool cur = false; // если истина - INK, если ложь - PAPER(так появится зернистость, чередование цвета INK и PAPER в тех местах, где цвета отличные от данных)
// опять пройдёмся по изображению
for (int yy = 0; yy < 8; yy++)
for (int xx = 0; xx < 8; xx++)
{
TColor c = Canvas->Pixels[260+x+xx][y+yy];
// далее чередование цветов
if (c != ink && c != paper)
{
if (cur) c = ink;
else c = paper;
cur = !cur;
}
Canvas->Pixels[260+x+xx][y+yy] = c;
}
}
Код:// принимает компонент RGB цвета
int Compr(int c)
{
if (c < 96) return 0; // если меньше 96, то этот цвет ближе к чёрному
if (c >= 224) return 255; // если больше 224, то цвет ближе к цвету повышенной яркости, чем к обычному
return 192;// иначе цвет обычной яркости
}
// принимает RGB цвет
TColor ColorMod(TColor c)
{
// выделим компоненты
int r = Compr(GetRValue(c));
int g = Compr(GetGValue(c));
int b = Compr(GetBValue(c));
// тут два варианта преобразования
int brig = (r!=192 && g!=192 && b!=192) ? 255 : 192; // повышенная яркость только тогда, когда все компоненты с повышенной яркостью(либо 0)
//int brig = (r==255 || g==255 || b==255) ? 255 : 192; // если хотябы 1 компонент повышеной яркости, то всё знакоместо будем считать повышенной яркости, иначе всё знакоместо обычной яркости
if (r != 0) r = brig;
if (g != 0) g = brig;
if (b != 0) b = brig;
return (TColor)RGB(r, g, b);
}
Результаты(оригинал - вариант 1 - вариант 2):
https://zx-pk.ru/attachment.php?atta...3&d=1581841327
Вложение 71531