Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.92/111: Рейтинг темы: голосов - 111, средняя оценка - 4.92
 Аватар для umnick_kh
311 / 249 / 44
Регистрация: 06.12.2010
Сообщений: 527

Аналоги для GetPixel/SetPixel

19.07.2011, 21:43. Показов 22926. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть такой код:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
            var bmp = pictureBox1.Image as Bitmap;
            for (int i = 0; i < bmp.Width; i++)
            {
                for (int j = 0; j < bmp.Height; j++)
                {
                    if (bmp.GetPixel(i, j) == Color.Blue)
                    {
                        bmp.SetPixel(i, j, Color.Red);
                    }
                    else
                    {
                        bmp.SetPixel(i, j, Color.White);
                    }
                }
            }
Но из-за GetPixel/SetPixel он работает очень долго, если картинка имеет большое разрешение. Примерно 10 секунд уходит. Как можно сократить это время хотя бы вдвое?
Читал про LockBits, но не разобрался. как им пользоваться.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
19.07.2011, 21:43
Ответы с готовыми решениями:

Преобразование цветного изображения, не используя GetPixel и SetPixel
Здравствуйте, у меня есть программа, которая обрабатывает черно-белое изображение. Мне нужно ее усовершенствовать,чтобы она обрабатывала...

Методы GetPixel\SetPixel BMP и стеганография
Подскажите, мне необходимо реализовать метод стеганографии &quot;&quot;замена палитры&quot;, следовательно нужно поместить как то свой текст в...

Как ускорить GetPixel и SetPixel?
Доброго времени суток! Столкнулся с медленной работой getpixel и setpixel. Читал про метод LockBits, но так и не смог разобраться с ним. ...

15
Почетный модератор
Эксперт .NET
 Аватар для NickoTin
8726 / 3678 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
19.07.2011, 22:15
Лучший ответ Сообщение было отмечено как решение

Решение

Компилировать с параметром unsafe.
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
// Использование
using ( var bmp = (Bitmap)Image.FromFile( @"i:\0.png" ) ) {
    ImageProcess( bmp );
    bmp.Save( @"i:\some0.png", ImageFormat.Png );
}
 
// Метод обработки
unsafe static void ImageProcess ( Bitmap bmp ) {
    // Только 24 битные изображения
    if ( bmp.PixelFormat != PixelFormat.Format24bppRgb )
        throw new ArgumentException();
 
    var bd = bmp.LockBits(
        new Rectangle( 0, 0, bmp.Width, bmp.Height ),
        ImageLockMode.ReadWrite,
        bmp.PixelFormat
    );
 
    var pStart = (byte*)bd.Scan0;
    var pEnd = (byte*)( pStart + bd.Stride * bd.Height );
 
    while ( pStart != pEnd ) {
        // BGR
        if ( *pStart == 255 && *( pStart + 1 ) == 0 && *( pStart + 2 ) == 0 ) {
            *pStart = *( pStart + 1 ) = 0;
            *( pStart + 2 ) = 255;
        } else {
            *pStart = *( pStart + 1 ) = *( pStart + 2 ) = 255;
        }
 
        pStart += 3;
    }
 
    bmp.UnlockBits( bd );
}
Изображение размером 1920x1440 обработало за несколько мс.
3
 Аватар для umnick_kh
311 / 249 / 44
Регистрация: 06.12.2010
Сообщений: 527
19.07.2011, 22:38  [ТС]
SSTREGG, спасибо, вроде бы понял, более-менее.
Но вот с такой строкой не справился, как ее переписать?
C#
1
int r = (bmp.GetPixel(i, j).R + bmp.GetPixel(i + 1, j + 1).R + bmp.GetPixel(i + 1, j).R + bmp.GetPixel(i, j + 1).R) / 4;
0
 Аватар для m0nax
1274 / 975 / 113
Регистрация: 12.01.2010
Сообщений: 1,971
19.07.2011, 23:10
гораздо удобней инкапсулировать всю эту возню с указателями в отдельный класс и юзать те же самые GetPixel
что собственно и сделано кучей народа, гуглится по запросам типа "fastbitmap net"
1
 Аватар для umnick_kh
311 / 249 / 44
Регистрация: 06.12.2010
Сообщений: 527
19.07.2011, 23:20  [ТС]
m0nax, ну а подробнее?
Всем спасибо, по совету m0nax нашел нужный класс, теперь все делается буквально за миллисекунды

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
86
87
88
89
90
91
92
93
94
95
96
   public unsafe class UnsafeBitmap
    {
        Bitmap bitmap;
 
  // three elements used for MakeGreyUnsafe
  int width;
  BitmapData bitmapData = null;
  Byte* pBase = null;
 
  public UnsafeBitmap(Bitmap bitmap)
  {
     this.bitmap = new Bitmap(bitmap);
  }
 
        public UnsafeBitmap(int width, int height)
        {
            this.bitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb);
        }
 
  public void Dispose()
  {
     bitmap.Dispose();
  }
 
  public Bitmap Bitmap
  {
     get
     {
    return(bitmap);
     }
  }
 
  private Point PixelSize
  {
     get
     {
    GraphicsUnit unit = GraphicsUnit.Pixel;
    RectangleF bounds = bitmap.GetBounds(ref unit);
 
    return new Point((int) bounds.Width, (int) bounds.Height);
     }
  }
 
  public void LockBitmap()
  {
     GraphicsUnit unit = GraphicsUnit.Pixel;
     RectangleF boundsF = bitmap.GetBounds(ref unit);
     Rectangle bounds = new Rectangle((int) boundsF.X,
    (int) boundsF.Y,
    (int) boundsF.Width,
    (int) boundsF.Height);
 
     // Figure out the number of bytes in a row
     // This is rounded up to be a multiple of 4
     // bytes, since a scan line in an image must always be a multiple of 4 bytes
     // in length. 
     width = (int) boundsF.Width * sizeof(PixelData);
     if (width % 4 != 0)
     {
    width = 4 * (width / 4 + 1);
     }
     bitmapData = 
    bitmap.LockBits(bounds, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
 
     pBase = (Byte*) bitmapData.Scan0.ToPointer();
  }
 
  public PixelData GetPixel(int x, int y)
  {
            PixelData returnValue = *PixelAt(x, y);
     return returnValue;
  }
 
        public void SetPixel(int x, int y, PixelData colour)
        {
            PixelData* pixel = PixelAt(x, y);
            *pixel = colour;
        }
 
  public void UnlockBitmap()
  {
     bitmap.UnlockBits(bitmapData);
     bitmapData = null;
     pBase = null;
  }
        public PixelData* PixelAt(int x, int y)
        {
            return (PixelData*)(pBase + y * width + x * sizeof(PixelData));
        }
    }
    public struct PixelData
    {
        public byte blue;
        public byte green;
        public byte red;
    }
3
Почетный модератор
Эксперт .NET
 Аватар для NickoTin
8726 / 3678 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
19.07.2011, 23:38
Лучший ответ Сообщение было отмечено как решение

Решение

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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
public Form1 ( ) {
    InitializeComponent();
 
    using ( var bmp = (Bitmap)Image.FromFile( @"i:\0.png" ) ) {
        var bb = new BufferedBitmap( bmp );
        var clr = Color.Empty;
 
        for ( int y = 0; y < bb.Height; ++y )
            for ( int x = 0; x < bb.Width; ++x ) {
                clr = bb.GetPixel( x, y );
                if ( clr.R == 0 && clr.G == 0 && clr.B == 128 )
                    bb.SetPixel( x, y, Color.FromArgb( 127, 255, 0, 0 ) );
                else
                    bb.SetPixel( x, y, Color.White );
            }
 
        bb.Unlock();
        bmp.Save( @"i:\some0.png", ImageFormat.Png );
    }
}
 
unsafe class BufferedBitmap
{
    Bitmap _bmp;
    BitmapData _bd;
    bool _locked;
    byte *pStart;
 
    public BufferedBitmap ( Bitmap bmp, bool @lock ) {
        _bmp = bmp;
 
        if ( @lock )
            Lock();
    }
 
    public BufferedBitmap ( Bitmap bmp )
        : this( bmp, true ) {
 
    }
 
    public void Lock ( ) {
        if ( !_locked ) {
            _bd = _bmp.LockBits(
                new Rectangle( 0, 0, _bmp.Width, _bmp.Height ),
                ImageLockMode.ReadWrite,
                _bmp.PixelFormat
            );
 
            pStart = (byte*)_bd.Scan0;
            _locked = true;
        }
    }
 
    public void Unlock ( ) {
        if ( !_locked )
            return;
 
        _bmp.UnlockBits( _bd );
 
        _locked = false;
    }
 
    public Bitmap Bitmap {
        get {
            return ( _locked ? null : _bmp );
        }
        set {
            if ( _locked )
                throw new Exception( "Image locked!" );
            if ( value == null )
                throw new NullReferenceException();
 
            _bmp = value;
        }
    }
 
    public int Width {
        get {
            return _bmp.Width;
        }
    }
 
    public int Height {
        get {
            return _bmp.Height;
        }
    }
 
    public void SetPixel ( int x, int y, Color clr ) {
        if ( !_locked )
            throw new Exception();
 
        switch ( _bd.PixelFormat ) {
        case PixelFormat.Format24bppRgb:
            SetPixel24( x, y, clr );
            break;
        case PixelFormat.Format32bppArgb:
            SetPixel32( x, y, clr );
            break;
        }
    }
 
    void SetPixel24 ( int x, int y, Color clr ) {
        var pMem = pStart + x * 3 + y * _bd.Stride;
 
        *pMem = clr.B;
        *( pMem + 1 ) = clr.G;
        *( pMem + 2 ) = clr.R;
    }
 
    void SetPixel32 ( int x, int y, Color clr ) {
        var pMem = pStart + x * 4 + y * _bd.Stride;
 
        *pMem = clr.B;
        *( pMem + 1 ) = clr.G;
        *( pMem + 2 ) = clr.R;
        *( pMem + 3 ) = clr.A;
    }
 
    public Color GetPixel ( int x, int y ) {
        if ( !_locked )
            throw new Exception();
 
        switch ( _bd.PixelFormat ) {
        case PixelFormat.Format24bppRgb:
            return GetPixel24( x, y );
        case PixelFormat.Format32bppArgb:
            return GetPixel32( x, y );
        default:
            throw new NotImplementedException();
        }
    }
 
    Color GetPixel24 ( int x, int y ) {
        var pMem = pStart + x * 3 + y * _bd.Stride;
 
        return Color.FromArgb(
            *( pMem + 2 ),
            *( pMem + 1 ),
            *pMem
        );
    }
 
    Color GetPixel32 ( int x, int y ) {
        var pMem = pStart + x * 4 + y * _bd.Stride;
 
        return Color.FromArgb(
            *( pMem + 3 ),
            *( pMem + 2 ),
            *( pMem + 1 ),
            *pMem
        );
    }
 
    public bool IsLocked {
        get {
            return _locked;
        }
    }
}
Пока писал m0nax уже предложил
Код работоспособен как для 24, так и для 32 битных изображений.
Работает помедленней, но эффект тот же.

Пускай будет для коллекции...
8
0 / 0 / 0
Регистрация: 30.04.2013
Сообщений: 26
13.06.2014, 20:43
NickoTin: Здравствуйте. Можете помочь с выбором fastbitmap? Интересует, какая из двух версий наиболее полноценна и функциональна?
первая: http://www.getcodesamples.com/... B/EEA2C640
вторая: https://github.com/alongubkin/... tBitmap.cs

С первой работал. Все нормально. Но если я правильно понял, она не освобождает ресурсы. Функция, в которой использую fastbitmap многократно загружает изображение и работает с пикселями. Через какое-то количество итераций зависает. outofmemory...

Спасибо.

Добавлено через 27 минут
Забыл третий вариант.
Третий: http://www.codeproject.com/Tip... ith-Csharp
0
Почетный модератор
Эксперт .NET
 Аватар для NickoTin
8726 / 3678 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
13.06.2014, 21:13
Цитата Сообщение от snegC Посмотреть сообщение
первая:
Ресурсы освобождаются (точнее изображение разблокируется), см. метод Dispose. За и исходный Bitmap отвечает тот кто использует класс.
Цитата Сообщение от snegC Посмотреть сообщение
https://github.com/alongubkin/FastBi.../FastBitmap.cs
Тоже освобождаются, но не просто разблокируется изображение, а освобождает ресурсы занятые изображением, не думаю что эта логика корректна в классе FastBitmap, т.к. в нём реализовывается только прямой доступ к пикселям и ничего более, это Helper, не более.
+ не помню точно, но вроде если изображение не разблокировано и вызывается Dispose, то будет исключение.
Цитата Сообщение от snegC Посмотреть сообщение
Третий
Похожий принцип, но работа происходит не с исходным изображением а с его копией (см. Marshal.Copy).

Вот еще варианты: Поиск соседних пикселей, там же Unril предложил вариант с распараллеливанием.
1
0 / 0 / 0
Регистрация: 30.04.2013
Сообщений: 26
13.06.2014, 21:43
NickoTin, немного запутался. Ваше мнение, какой из 4х Вам больше нравится и более корректен в работе с памятью?
0
Почетный модератор
Эксперт .NET
 Аватар для NickoTin
8726 / 3678 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
13.06.2014, 21:47
snegC, 1й и те что я привел по ссылке.
1
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
14.06.2014, 04:17
я лично использую такую заготовку для работы с bmp:

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
using System;
using System.Drawing;
using System.Drawing.Imaging;
 
namespace Helpers
{
    public static class BitmapHelper
    {
        struct Pixel : IEquatable<Pixel>
        {
            
// ReSharper disable UnassignedField.Compiler
            public byte Blue;
            public byte Green;
            public byte Red;
 
            public bool Equals(Pixel other)
            {
                return Red == other.Red && Green == other.Green && Blue == other.Blue;
            }
        }
 
        public static Color[,] GetPixels(this Bitmap bmp)
        {
            return ProcessBitmap(bmp, pixel => Color.FromArgb(pixel.Red, pixel.Green, pixel.Blue));
        }
 
        public static float[,] GetBrightness(this Bitmap bmp)
        {
            return ProcessBitmap(bmp, pixel => Color.FromArgb(pixel.Red, pixel.Green, pixel.Blue).GetBrightness());
        }
 
        public static unsafe T[,] ProcessBitmap<T>(this Bitmap bitmap, Func<Pixel, T> func)
        {
            var lockBits = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly,
                                       bitmap.PixelFormat);
            int padding = lockBits.Stride - (bitmap.Width*sizeof (Pixel));
 
            int width = bitmap.Width;
            int height = bitmap.Height;
 
            var result = new T[height, width];
 
            var ptr = (byte*) lockBits.Scan0;
 
            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    var pixel = (Pixel*) ptr;
                    result[i, j] = func(*pixel);
                    ptr += sizeof (Pixel);
                }
                ptr += padding;
            }
 
            bitmap.UnlockBits(lockBits);
 
            return result;
        }
    }
}
0
 Аватар для Orodunaar
0 / 0 / 0
Регистрация: 24.07.2013
Сообщений: 46
14.06.2014, 05:39
NickoTin, как использовать ваш пример BufferedBitmap с pictureBox?
У меня после
C#
1
Application.Run(new MainForm());
выдает исключение "Неверный параметр". Подскажите, что я делаю не так?
Вот код:
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
        void Button1Click(object sender, EventArgs e)
        {
            Image img;
            using ( var bmp = (Bitmap)SreenShot())
            {
                var bb = new BufferedBitmap( bmp );
                var clr = Color.Empty;
                for ( int y = 0; y < bb.Height; ++y )
                    for ( int x = 0; x < bb.Width; ++x )
                {
                    clr = bb.GetPixel( x, y );
                    if ( clr.R == 0 && clr.G == 0 && clr.B == 128 )
                        bb.SetPixel( x, y, Color.FromArgb( 127, 255, 0, 0 ) );
                    else
                        bb.SetPixel( x, y, Color.Blue );
                }
                bb.Unlock();
                bmp.Save( @"some0.png", ImageFormat.Png );
                img = (Image)bmp;
            }
            pictureBox1.BackgroundImage = img;          
        }       
        public Image SreenShot()
        {
            Graphics gr;
            Bitmap bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height,
                                    PixelFormat.Format32bppRgb);
            gr = Graphics.FromImage(bmp);
            gr.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y,
                              0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);
            Image img = (Image)bmp;
            return img;
        }
0
0 / 0 / 0
Регистрация: 30.04.2013
Сообщений: 26
14.06.2014, 10:26
NickoTin, Огромное спасибо. Попробовал оба варианта. Ваш оказался немногим быстрее. При работе с большим количеством картинок память больше не забивается. Еще раз спасибо.
0
169 / 132 / 29
Регистрация: 16.02.2013
Сообщений: 867
14.06.2014, 13:50
umnick_kh, используйте библиотеку autoit, она как раз для этого предназначена. Там это делается с помощью нескольких строк кода
0
0 / 0 / 0
Регистрация: 25.07.2013
Сообщений: 163
23.12.2014, 22:27
делаю по первому варианту приведенному snegC, но получается ерунда какая-то. Вот код просто для теста.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var rand = new Random();
            
            var massive = new int [1600,900];
            var bmp = new Bitmap(900,1600);
            var Draw = new FastBitmap(bmp);
            for (int i = 0; i < 1600; i++) 
            {
                for (int j = 0; j < 900; j++)
                {
                    massive[i,j]= 255;
                }
            }
           int maxvalue = massive.Cast<int>().Max();
           
        for (int i = 0; i < 1600; i++) 
            {
                for (int j = 0; j < 900; j++)
                {
                    Draw.SetColor(j,i, Color.FromArgb((int)(massive[i,j]*255/maxvalue),(int)(massive[i,j]*255/maxvalue),(int)(massive[i,j]*255/maxvalue)));
                }
            }
        pictureBox1.Image=bmp;

Результат:
Миниатюры
Аналоги для GetPixel/SetPixel  
0
0 / 0 / 0
Регистрация: 25.07.2013
Сообщений: 163
24.12.2014, 20:27
разобрался, забыл Dispose();
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
24.12.2014, 20:27
Помогаю со студенческими работами здесь

Игра Жизнь пиксельный метод. SetPixel,GetPixel тормозит
Добрый день, Форумчани. С друзьями решили реализовать &quot;игра жизнь&quot;(смотреть на википедии кто не знает) на разных платформах изхищренными...

SetPixel не поддерживается для изображений, имеющих форматы с индексированными точками
Выделяю прямоугольную область на цветной картинке 1.Требуется вывести одновременно выделенный черно-белый(бинаризированный) график с...

Не работает: COLORREF c; BYTE r,g,b; c=GetPixel(i,j); r=GetRValue(c); g=... b=.... ..... c=RGB(r,g,b); SetPixel(i,j,c);
у меня не получается посмотри: ...... COLORREF c; BYTE r,g,b; c=GetPixel(i,j); r=GetRValue(c); g=... b=.... ..... ...

SetPixel и GetPixel. Одна точка закрашивает другую, но не должна
Здравствуйте. Задача: нарисовать прямую заданной толщины с полоской в 1 пиксель по середине. Как бы не проблема, но накидав код, обнаружил,...

Подобрать аналоги для транзисторов. Для приемо-передатчика 27 МГц
Преподаватель дал задание. Подобрать схему передатчика и приемника на 27 МГц. Собрать ее сначала в Multisim (лучше) или ДипТрейс (не...


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

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru