Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.62/26: Рейтинг темы: голосов - 26, средняя оценка - 4.62
1 / 1 / 1
Регистрация: 04.05.2016
Сообщений: 266

Необычный фильтр для картинок

04.08.2019, 11:56. Показов 5446. Ответов 62
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Решил написать фильтр для картинок в стиле дальтонизма с тремя режимами (Протанопия,Дейтеранопия,Тританопия)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
float p(float chislo,float protsent){
    return chislo*protsent/100.0;
}
 
TColor Protan(TColor old)
{
long double r,g ,b;
r=GetRValue(old);
g=GetGValue(old);
b=GetBValue(old);
long double  r1,g1,b1;
r1=p(r,20)+p(g,99)-p(b,19);
g1=p(r,16)+p(g,79)+p(b,4);
b1=p(r,1)-p(g,1)+p(b,100);
if (r1>255) r1=255;
if (g1>255) g1=255;
if (b1>255) b1=255;
if (r1<0) r1=0;
if (g1<0) g1=0;
if (b1<0) b1=0;
return  (TColor) RGB (r1, g1, b1);
}
 
TColor Deutran(TColor old)
{
long double r,g ,b;
r=GetRValue(old);
g=GetGValue(old);
b=GetBValue(old);
long double  r1,g1,b1;
r1=p(r,43)+p(g,72)-p(b,15);
g1=p(r,34)+p(g,57)+p(b,9);
b1=p(g,3)-p(r,2)+p(b,100);
if (r1>255) r1=255;
if (g1>255) g1=255;
if (b1>255) b1=255;
if (r1<0) r1=0;
if (g1<0) g1=0;
if (b1<0) b1=0;
return  (TColor) RGB (r1, g1, b1);
}
 
TColor Tritan(TColor old)
{
long double r,g ,b;
r=GetRValue(old);
g=GetGValue(old);
b=GetBValue(old);
long double  r1,g1,b1;
r1=p(r,97)+p(g,11)-p(b,8);
g1=p(r,2)+p(g,82)+p(b,16);
b1=p(g,88)-p(r,6)+p(b,18);
if (r1>255) r1=255;
if (g1>255) g1=255;
if (b1>255) b1=255;
if (r1<0) r1=0;
if (g1<0) g1=0;
if (b1<0) b1=0;
return  (TColor) RGB (r1, g1, b1);
}
 
TBitmap* Linear(int typ)
{
TJPEGImage *jpg = new TJPEGImage();
jpg->LoadFromFile(filen);
Graphics::TBitmap *bmp1, *bmp2;
bmp1 = new Graphics::TBitmap();
bmp1->Assign(jpg);
if (typ==0) return bmp1;
if(bmp1->PixelFormat == pf24bit)
{
RGBTRIPLE*ptr;
for(int y = 0; y < bmp1->Height; y++)
{
ptr = (RGBTRIPLE*)bmp1->ScanLine[y];
for (int x = 0; x < bmp1->Width; x++)
{
if (typ==1) bmp1->Canvas->Pixels[x][y]=Protan((TColor)RGB(ptr[x].rgbtRed, ptr[x].rgbtGreen, ptr[x].rgbtBlue));
else if (typ==2)    bmp1->Canvas->Pixels[x][y]=Deutran((TColor)RGB(ptr[x].rgbtRed, ptr[x].rgbtGreen, ptr[x].rgbtBlue));
else if (typ==3)    bmp1->Canvas->Pixels[x][y]=Tritan((TColor)RGB(ptr[x].rgbtRed, ptr[x].rgbtGreen, ptr[x].rgbtBlue));
}
}
}
return bmp1;
}
Но работает медленно. В чем проблема?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
04.08.2019, 11:56
Ответы с готовыми решениями:

GetOpenFileName - установить фильтр для текстовых файлов и картинок
Добрый вечер. Сделал открытие и показ только txt файлов, еще хочу что бы картинки показывало. Как дополнить? ...

Необычный код - необычный результат.
Бросте на форму PaintBox и сделайте Align alClient. В OnPaint напишите так: procedure TForm1.PaintBox1Paint(Sender: TObject); var ...

Необычный вопрос, но как раскрутить сервис для людей?
Может немного необычный вопрос, но хочется узнать, если ты создал сервис, то как можно донести информацию о нем? Куда можно обращаться, что...

62
2637 / 1648 / 267
Регистрация: 19.02.2010
Сообщений: 4,370
08.08.2019, 20:51
Лучший ответ Сообщение было отмечено viramir как решение

Решение

Студворк — интернет-сервис помощи студентам
Цитата Сообщение от FFPowerMan Посмотреть сообщение
А вот просто интересно, когда автор считает какой-либо цветовой канал, например по этой формуле:
> r1 = p(r,20) + p(g,99) - p(b,19);
и пусть у нас будет r1 типа int, то тогда какое число будет как "потолок" в этом числе.
Т.е. понятие "потолок" - это как-бы "максимум" числа, для числа типа Байт "потолок" будет 255. А какой будет "потолок" у r1? 2*255 или 3*255?
255 или чуть больше (если сумма вторых аргументов у функции p() будет >100, что иногда в коде ТСа возникало).
Всё легко (школьная математика) определяется после взгляда на потроха функции p(), инлайна её тушки в формулу для любого ri, и вынесения общих множителей за скобки.
В общем, при доступном для любого канала максимуме в 255 (предполагаем, что берём белый цвет и там все каналы будут по-максимуму) после вынесения общего за скобки имеем https://www.cyberforum.ru/cgi-bin/latex.cgi?r_i=\frac{255}{100}*(c1+c2+c3), где c1+c2+c3 - сумма вторых аргументов у функции p(), и эта сумма равна или примерно равна 100, т.е. с сотней в делителе она сократится, т.е. останется 255, либо 255*1.01 (если c1+c2+c3=101).

ЗЫ. Когда писал "сумма вторых аргументов" - предполагал, что знаки перед вызовами p() перешли в эти аргументы.
0
1 / 1 / 1
Регистрация: 04.05.2016
Сообщений: 266
08.08.2019, 20:54  [ТС]
Цитата Сообщение от VTsaregorodtsev Посмотреть сообщение
255 или чуть больше (если сумма вторых аргументов у функции p() будет >100, что иногда в коде ТСа возникало).
Всё легко (школьная математика) определяется после взгляда на потроха функции p(), инлайна её тушки в формулу для любого ri, и вынесения общих множителей за скобки.
В общем, при доступном для любого канала максимуме в 255 (предполагаем, что берём белый цвет и там все каналы будут по-максимуму) после вынесения общего за скобки имеем https://www.cyberforum.ru/cgi-bin/latex.cgi?r_i=\frac{255}{100}*(c1+c2+c3), где c1+c2+c3 - сумма вторых аргументов у функции p(), и эта сумма равна или примерно равна 100, т.е. с сотней в делителе она сократится, т.е. останется 255, либо 255*1.01 (если c1+c2+c3=101).

ЗЫ. Когда писал "сумма вторых аргументов" - предполагал, что знаки перед вызовами p() перешли в эти аргументы.
p() это просто взятие процента.
0
 Аватар для FFPowerMan
2156 / 1236 / 508
Регистрация: 11.10.2018
Сообщений: 6,249
09.08.2019, 11:43
Ну и давайте без деления, эту же радугу, чтобы нам всем разницу увидеть.
0
1 / 1 / 1
Регистрация: 04.05.2016
Сообщений: 266
09.08.2019, 11:48  [ТС]
Цитата Сообщение от FFPowerMan Посмотреть сообщение
Ну и давайте без деления, эту же радугу, чтобы нам всем разницу увидеть.
1
1 / 1 / 1
Регистрация: 04.05.2016
Сообщений: 266
09.08.2019, 20:00  [ТС]
Цитата Сообщение от FFPowerMan Посмотреть сообщение
Ну и давайте без деления, эту же радугу, чтобы нам всем разницу увидеть.
Значит выводы с делением были неверны?
0
 Аватар для FFPowerMan
2156 / 1236 / 508
Регистрация: 11.10.2018
Сообщений: 6,249
10.08.2019, 09:59
Да фиг знает, я до сих пор не могу понять какой "потолок" у новых значений цветовых каналов. Чем это обосновать, так чтобы понятно было?
0
1 / 1 / 1
Регистрация: 04.05.2016
Сообщений: 266
10.08.2019, 10:30  [ТС]
Цитата Сообщение от FFPowerMan Посмотреть сообщение
Да фиг знает, я до сих пор не могу понять какой "потолок" у новых значений цветовых каналов. Чем это обосновать, так чтобы понятно было?
Ну по моему он больше 255 так как при неправильном расчете появляются пятна
0
 Аватар для FFPowerMan
2156 / 1236 / 508
Регистрация: 11.10.2018
Сообщений: 6,249
10.08.2019, 10:47
Вообще, надо Ваши формулы:
Цитата Сообщение от viramir Посмотреть сообщение
C++
1
r1=p(r,20)+p(g,99)-p(b,19);
вот так писать:
C++
1
r1 = r*0.2 + g*0.99 - b*0.19;
Так функция меньше вызывается(protsent) и в теории должно быстрее работать. Попробуйте на практике, отпишите потом, пожалуйста.
0
1 / 1 / 1
Регистрация: 04.05.2016
Сообщений: 266
10.08.2019, 11:06  [ТС]
Цитата Сообщение от FFPowerMan Посмотреть сообщение
Вообще, надо Ваши формулы:

вот так писать:
C++
1
r1 = r*0.2 + g*0.99 - b*0.19;
Так функция меньше вызывается(protsent) и в теории должно быстрее работать. Попробуйте на практике, отпишите потом, пожалуйста.
Спасибо. Действительно лучше. Я вообще избавился от p()
Вот оригинал и результат всех четырех режимов работы




0
 Аватар для FFPowerMan
2156 / 1236 / 508
Регистрация: 11.10.2018
Сообщений: 6,249
10.08.2019, 18:18
Еще можно ускорить. Сейчас все преобразования находятся в функции Linear и она вызывается каждой из кнопок. Но я бы сделал по-другому и полагаю, что делают не совсем так. А делают вот так:
в обработчике события от каждой кнопки будет свое преобразование. Открытие и назначение файла лучше вынести за скобки, а обработчик события OnClick каждой кнопки будет работать с BMP.
Дальше, функции Protan, Deutran, Tritan и GrayScale также убираем и их код помещаем в обработчике события каждой кнопки, соответственно.
Сам код в каждой кнопке будет выглядеть примерно так:
C++
1
2
3
4
5
6
//Псеводкод:
for(y по строкам)
    for(x по столбцам)
    {
        //тут будет код, соответствующий преобразованию
    }
Попробуйте, потом скажете быстрее стало или как?
0
1 / 1 / 1
Регистрация: 04.05.2016
Сообщений: 266
10.08.2019, 18:23  [ТС]
Цитата Сообщение от FFPowerMan Посмотреть сообщение
Еще можно ускорить. Сейчас все преобразования находятся в функции Linear и она вызывается каждой из кнопок. Но я бы сделал по-другому и полагаю, что делают не совсем так. А делают вот так:
в обработчике события от каждой кнопки будет свое преобразование. Открытие и назначение файла лучше вынести за скобки, а обработчик события OnClick каждой кнопки будет работать с BMP.
Дальше, функции Protan, Deutran, Tritan и GrayScale также убираем и их код помещаем в обработчике события каждой кнопки, соответственно.
Сам код в каждой кнопке будет выглядеть примерно так:
C++
1
2
3
4
5
6
//Псеводкод:
for(y по строкам)
    for(x по столбцам)
    {
        //тут будет код, соответствующий преобразованию
    }
Попробуйте, потом скажете быстрее стало или как?
попробую. Но я при открытии файла вызывал все варианты Linear и записывал результат в каждые TBitmap
правильно ли так
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void __fastcall TForm1::OpenExecute(TObject *Sender)
{
 if (op1->Execute())
{
filen=op1->FileName;
TJPEGImage *jpg = new TJPEGImage();
jpg->LoadFromFile(filen);
Graphics::TBitmap *bmp1, *bmp2;
bmp1 = new Graphics::TBitmap();
bmp1->Assign(jpg);
im1=Linear(bmp1,0);
im2=Linear(bmp1,1);
im3=Linear(bmp1,2);
im4=Linear(bmp1,3);
im5=Linear(bmp1,4);
Image1->Picture->Bitmap=im1;
BNorm->Font->Style=TFontStyles()<< fsBold;
MNorm->Checked=True;
BProtan->Font->Style=TFontStyles()>> fsBold;
BDeuteran->Font->Style=TFontStyles()>> fsBold;
BTritan->Font->Style=TFontStyles()>>fsBold;
BMonoChr->Font->Style=TFontStyles()>> fsBold;
}
}
А в кнопках лишь подгружал нужное,используя ActionList

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
void __fastcall TForm1::TritanExecute(TObject *Sender)
{
//Выделение активной кнопки жирным
BNorm->Font->Style=TFontStyles()>> fsBold;
BProtan->Font->Style=TFontStyles()>> fsBold;
BDeuteran->Font->Style=TFontStyles()>> fsBold;
BTritan->Font->Style=TFontStyles()<< fsBold;
BMonoChr->Font->Style=TFontStyles()>> fsBold;
//Пункт строки меню помечен
 MTritan->Checked=True;
//Загрузка готового изображения
Image1->Picture->Bitmap=im4;
}
0
 Аватар для FFPowerMan
2156 / 1236 / 508
Регистрация: 11.10.2018
Сообщений: 6,249
10.08.2019, 18:27
Ну правильно-то правильно, только так медленнее будет работать из-за того что:
1) Функции вызываются для каждого пикселя(Protan, Deutran, Tritan и GrayScale);
2) Условие, которое выбирает обработку тоже как-бы неускоряет ее.
0
1 / 1 / 1
Регистрация: 04.05.2016
Сообщений: 266
10.08.2019, 18:36  [ТС]
Цитата Сообщение от FFPowerMan Посмотреть сообщение
Ну правильно-то правильно, только так медленнее будет работать из-за того что:
1) Функции вызываются для каждого пикселя(Protan, Deutran, Tritan и GrayScale);
2) Условие, которое выбирает обработку тоже как-бы неускоряет ее.
А что делать,чтобы было не для каждого пикселя?

Добавлено через 4 минуты
Цитата Сообщение от FFPowerMan Посмотреть сообщение
Ну правильно-то правильно, только так медленнее будет работать из-за того что:
1) Функции вызываются для каждого пикселя(Protan, Deutran, Tritan и GrayScale);
2) Условие, которое выбирает обработку тоже как-бы неускоряет ее.
Проблема в том,что я переделал функцию Linear,еще более запутал код а как распутать не знаю
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
TBitmap* Linear(TBitmap* oldbmp,int typ)
{
TBitmap* bmp1 = new TBitmap();
bmp1->Assign(oldbmp);
TCanvas * canva=bmp1->Canvas;
if (typ==0) return oldbmp;
RGBTRIPLE*ptr;
for(int y = 0; y < bmp1->Height; y++)
{
ptr = (RGBTRIPLE*)bmp1->ScanLine[y];
for (int x = 0; x < bmp1->Width; x++)
{
if (typ==1) canva->Pixels[x][y]=Protan((TColor)RGB(ptr[x].rgbtRed, ptr[x].rgbtGreen, ptr[x].rgbtBlue));
else if (typ==2) canva->Pixels[x][y]=Deuteran((TColor)RGB(ptr[x].rgbtRed, ptr[x].rgbtGreen, ptr[x].rgbtBlue));
else if (typ==3) canva->Pixels[x][y]=Tritan((TColor)RGB(ptr[x].rgbtRed, ptr[x].rgbtGreen, ptr[x].rgbtBlue));
else if (typ==4) canva->Pixels[x][y]=Gray((TColor)RGB(ptr[x].rgbtRed, ptr[x].rgbtGreen, ptr[x].rgbtBlue));
}
}
 
return bmp1;
}
0
 Аватар для FFPowerMan
2156 / 1236 / 508
Регистрация: 11.10.2018
Сообщений: 6,249
10.08.2019, 18:38
Цитата Сообщение от viramir Посмотреть сообщение
А что делать,чтобы было не для каждого пикселя?
- Ну пропускайте пиксели сколько Вам надо. В циклах for пишите:
C++
1
for(x = 0; x < Width; x += 2)
0
1 / 1 / 1
Регистрация: 04.05.2016
Сообщений: 266
10.08.2019, 18:39  [ТС]
FFPowerMan, пропускать не надо,мне нужно без этиж нагромождений
C++
1
Deuteran((TColor)RGB(ptr[x].rgbtRed, ptr[x].rgbtGreen, ptr[x].rgbtBlue));
0
 Аватар для FFPowerMan
2156 / 1236 / 508
Регистрация: 11.10.2018
Сообщений: 6,249
10.08.2019, 18:43
Цитата Сообщение от viramir Посмотреть сообщение
Проблема в том,что я переделал функцию Linear,еще более запутал код а как распутать не знаю
- Ну тут проще сначала начать. Только новый проект не удаляйте. Новый скопируйте просто и все. В новом сделайте, как я сказал. Некоторые вещи начните с 0. Потом код докопируете и все.

Добавлено через 2 минуты
Цитата Сообщение от viramir Посмотреть сообщение
RGBTRIPLE* ptr;
- Так а вот это зачем? Вы же взяли Канву и теперь просто обращайтесь к ней, точнее к ее пикселям:
C++
1
canva->Pixels[x][y]
0
 Аватар для Meoww
8 / 8 / 2
Регистрация: 02.10.2014
Сообщений: 112
10.08.2019, 18:56
Просто выкиньте вот это из кода - canva->Pixels, это тормоза, а вы там с формулами играетесь
0
1 / 1 / 1
Регистрация: 04.05.2016
Сообщений: 266
10.08.2019, 19:02  [ТС]
Цитата Сообщение от Meoww Посмотреть сообщение
Просто выкиньте вот это из кода - canva->Pixels, это тормоза, а вы там с формулами играетесь
А как же изменить цвет пикселей?

Добавлено через 3 минуты
Цитата Сообщение от Meoww Посмотреть сообщение
Просто выкиньте вот это из кода - canva->Pixels, это тормоза, а вы там с формулами играетесь
Кроме этого я не знаю,как обработать пиксель
0
 Аватар для FFPowerMan
2156 / 1236 / 508
Регистрация: 11.10.2018
Сообщений: 6,249
10.08.2019, 19:12
Цитата Сообщение от Meoww Посмотреть сообщение
Просто выкиньте вот это из кода - canva->Pixels,
- А как еще можно к Канве обратиться без OpenGL?
0
1 / 1 / 1
Регистрация: 04.05.2016
Сообщений: 266
10.08.2019, 19:29  [ТС]
Цитата Сообщение от FFPowerMan Посмотреть сообщение
- А как еще можно к Канве обратиться без OpenGL?
Чудом смог обойтись без Pixels
Работает за секунду
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
TBitmap* bmp=new TBitmap();
//Загружаю заранее считанный с файла Bitmap
bmp->Assign(im1);
Form1->Image1->Picture->Bitmap->Assign(bmp);
TCanvas * canva=Form1->Image1->Picture->Bitmap->Canvas;
RGBTRIPLE*ptr;
for(int y = 0; y < bmp->Height; y++)
{
ptr = (RGBTRIPLE*)bmp->ScanLine[y];
for (int x = 0; x < bmp->Width; x++)
{
int  r,g ,b;
r=ptr[x].rgbtRed;
g=ptr[x].rgbtGreen;
b=ptr[x].rgbtBlue;
int   r1,g1,b1;
r1=r*0.20+g*0.99-b*0.19;
g1=r*0.16+g*0.79+b*0.04;
b1=r*0.01-g*0.01+b;
if (r1>255) r1=255;
if (g1>255) g1=255;
if (b1>255) b1=255;
if (r1<0) r1=0;
if (g1<0) g1=0;
if (b1<0) b1=0;
ptr[x].rgbtRed=r1;
ptr[x].rgbtGreen=g1;
ptr[x].rgbtBlue=b1;
}
}
Form1->Image1->Picture->Bitmap->Assign(bmp);
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
10.08.2019, 19:29
Помогаю со студенческими работами здесь

Необычный join (применить условие where для первой таблицы, а потом where для результата join)
мне нужно прежде чем джоинить, применить условие where для первой таблицы. а потом where для результат джойна. как быть? в строение join...

Конфигурация сайта для Magento 2. Cache TTL для картинок
Сайт на Magento 2.3 На сайте имеются картинки продуктов хранящиеся в /public_html/pub/media/catalog/product Также есть самописный...

Программа для вывода картинок (карточки для изучения ин.яз)
Люди добрые, меня зовут Иляна. Извините что я к вам обращаюсь. Дело в том что сейчас я и моя группа изучаем иностранный язык (а именно...

Фильтр для питания для применения в автомобилях
Разработал источник питания на постоянное напряжения для применения в автомобилях Типовое потребление оборудования около 10А. Так...

Фильтр по форме по нескольким логическим полям с использованием кнопки Общий фильтр
Здравствуйте! Есть простая таблица и созданная форма. Идея в том, чтобы ставя галки осуществлять поиск (с помощью кнопки общий фильтр...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
Установка Emscripten SDK (emsdk) и CMake на Windows для сборки C и C++ приложений в WebAssembly (Wasm)
8Observer8 30.01.2026
Чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. Система контроля версиями Git. . .
Подключение Box2D v3 к SDL3 для Android: физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
Влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru