Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.60/25: Рейтинг темы: голосов - 25, средняя оценка - 4.60
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,904
.NET 4.x

Быстрая попиксельная замена нескольких цветов у картинки и остальная работа с графикой

07.08.2020, 16:20. Показов 5660. Ответов 61
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте.
Подскажите как быстро делать замену нескольких цветов у картинки + накладывание картинки на картинку или отрисовка в нужных позициях. И также маштабирование Для точности нужно использовать циклы по пиксельно или както по другому но нужно заменять только при полном совпадении.
Но мне нужен быстрые способы. Стандартные методы делают это медленно. OpenGL да, но я вот тока не знаю как в нем работать. Там для меня трудная система коррдинат по Float системе. Да и плюс может есть чтото полегче

Короче надеюсь есть те кто ответят. Уроки, примеры хоть что

И так. Нужны 3 вещи.

1. Накладывание одной картинки на другую.
2. Отрисовка нескольких картинок в нужных позициях. Именно что не 1 картинка а несколько.
3. Замена массива цветов (Предположим 10 - 15 цветов) в картинки. Тоесть есть массив с исходными цветами а есть на которые нужно менять.
4. Изменение маштаба картинки / картинок

Первые 2 по сути как 1 идет просто в 1 случае используеться 0 координата.

И повторюсь. Интересуют быстрая реализация на уровне реализации игр но это не игра а утилита. Ну короче быстро это делать.
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
07.08.2020, 16:20
Ответы с готовыми решениями:

Быстрая работа с графикой
Добрый день. интересует способ быстрого выведения множества пикселей на экран. мне не нужны полигоны и другие сложные объекты, нужны именно...

Попиксельная обработка картинки средствами VBA
Доброго всем времени суток. Проблемка: Есть графический файл. Чтоб не распылятся об различиях кодировки данных о цвете в разных форматах...

Есть н цветов разных видов. Составьте все возможные сочетания букетов из всех этих цветов. Количество цветов и их названия вводит пользователь
Есть n цветов разных видов. Составьте все возможные сочетания букетов из всех этих цветов. Количество цветов и их названия вводит...

61
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,904
08.08.2020, 14:28  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Someone007 Посмотреть сообщение
Забейте на других. Если им нужен ваш софт, то обновятся и установят всё что нужно, никуда не денутся...
Система они точно ставить не будут. Ну с другой стороны возможно и стоит на Net Framework 4.6 перейти или какой там но точно не на Net Core 3 так как повторяю в VS 2019 конструктора форм на WinForms нету.

Добавлено через 1 минуту
Цитата Сообщение от Someone007 Посмотреть сообщение
Ну и вообще ускорить проход по массиву пикселей можно например распараллелив обработку на несколько потоков.
Мне нужен пример. Я могу скинуть что там нужно для примера. Картинку и цвета в html я скинул ну могу перевестьи в RGB.

Добавлено через 2 минуты
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Система они точно ставить не будут. Ну с другой стороны возможно и стоит на Net Framework 4.6 перейти или какой там но точно не на Net Core 3 так как повторяю в VS 2019 конструктора форм на WinForms нету.
Вообщето вру. И действительно есть. Но появился только после того как я открыл параметры проекта.

Добавлено через 31 минуту
Чет не могу понять. А как по пиксельную замену цвета делать в SixLabors.ImageSharp?
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,576
08.08.2020, 15:03
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Чет не могу понять. А как по пиксельную замену цвета делать в SixLabors.ImageSharp?
Например так:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Dictionary<Rgba32, Rgba32> colorReplacements = new Dictionary<Rgba32, Rgba32>
{
    [new Rgba32(0xFF, 0xDA, 0x91)] = new Rgba32(0x00, 0x48, 0xFF),
    [new Rgba32(0xDA, 0xB6, 0x6D)] = new Rgba32(0x00, 0x48, 0xDA),
    [new Rgba32(0xB6, 0x91, 0x48)] = new Rgba32(0x00, 0x48, 0xB6),
    [new Rgba32(0x91, 0x6D, 0x24)] = new Rgba32(0x00, 0x48, 0x91),
    [new Rgba32(0x6D, 0x48, 0x00)] = new Rgba32(0x00, 0x24, 0x6D),
    [new Rgba32(0x48, 0x24, 0x24)] = new Rgba32(0x00, 0x24, 0x48),
    [new Rgba32(0x24, 0x00, 0x00)] = new Rgba32(0x00, 0x00, 0x24),
};
 
using (SixLabors.ImageSharp.Image<Rgba32> image = SixLabors.ImageSharp.Image.Load<Rgba32>("Пример.png"))
{
    for (int y = 0; y < image.Height; y++)
    {
        Span<Rgba32> pixelRowSpan = image.GetPixelRowSpan(y);
        for (int x = 0; x < image.Width; x++)
        {
            if (colorReplacements.TryGetValue(pixelRowSpan[x], out var cn))
                pixelRowSpan[x] = cn;
        }
    }
}
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,904
08.08.2020, 15:16  [ТС]
Чет не работает замена. Хотя вот эта строчка pixelRowSpan[x] = cn; срабатывает.
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,576
08.08.2020, 15:31
Как вы определили что не работает? Изображение измененное хоть сохранили куда нибудь?
C#
1
image.SaveAsPng("xxx.png");
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,904
08.08.2020, 15:41  [ТС]
В принципе логично. Ведь замена происходит в pixelRowSpan а как обратно та его передать image?

Добавлено через 9 минут
Вообще вот полный код и не работает
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
private void button1_Click(object sender, EventArgs e)
        {
            Dictionary<Rgba32, Rgba32> colorReplacements = new Dictionary<Rgba32, Rgba32>
            {
                [new Rgba32(0xFF, 0xDA, 0x91)] = new Rgba32(0x00, 0x48, 0xFF),
                [new Rgba32(0xDA, 0xB6, 0x6D)] = new Rgba32(0x00, 0x48, 0xDA),
                [new Rgba32(0xB6, 0x91, 0x48)] = new Rgba32(0x00, 0x48, 0xB6),
                [new Rgba32(0x91, 0x6D, 0x24)] = new Rgba32(0x00, 0x48, 0x91),
                [new Rgba32(0x6D, 0x48, 0x00)] = new Rgba32(0x00, 0x24, 0x6D),
                [new Rgba32(0x48, 0x24, 0x24)] = new Rgba32(0x00, 0x24, 0x48),
                [new Rgba32(0x24, 0x00, 0x00)] = new Rgba32(0x00, 0x00, 0x24),
            };
 
            using (SixLabors.ImageSharp.Image<Rgba32> img = SixLabors.ImageSharp.Image.Load<Rgba32>("Пример.png"))
            {
                for (int y = 0; y < img.Height; y++)
                {
                    Span<Rgba32> pixelRowSpan = img.GetPixelRowSpan(y);
                    for (int x = 0; x < img.Width; x++)
                    {
                        if (colorReplacements.TryGetValue(pixelRowSpan[x], out var cn))
                            pixelRowSpan[x] = cn;
                    }
                }
 
                img.SaveAsPng("Пример2.png");
            }
 
            pictureBox1.Image = null;
 
            pictureBox1.Image = new Bitmap("Пример2.png");
        }
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,576
08.08.2020, 15:49
У меня работает, визуально видно что цвета в файлах отличаются...
Миниатюры
Быстрая попиксельная замена нескольких цветов у картинки и остальная работа с графикой  
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,904
08.08.2020, 15:57  [ТС]
Да но вот только надо везде менять а вообще должно было поменяться все желтые регионы на красные.
Это неправильно уже красит. Тоесть все пиксели с цветом 0xFF, 0xDA, 0x91 доллжны меняться на 0x00, 0x48, 0xFF и так далее пока все не измениться. Так что какойто косяк в методе.
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,576
08.08.2020, 16:03
Значит цвета не те у вас заданы для замены...
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,904
08.08.2020, 16:06  [ТС]
Как будтобы только последние цвета и заменяет. Чета не так.
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,576
08.08.2020, 16:10
BitmapLocker (https://github.com/vano-maisuradze/lock-bitmap) с первой страницы дает абсолютно такой же результат
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
Dictionary<Color, Color> colorReplacements = new Dictionary<Color, Color>
{
    [Color.FromArgb(0xFF, 0xDA, 0x91)] = Color.FromArgb(0x00, 0x48, 0xFF),
    [Color.FromArgb(0xDA, 0xB6, 0x6D)] = Color.FromArgb(0x00, 0x48, 0xDA),
    [Color.FromArgb(0xB6, 0x91, 0x48)] = Color.FromArgb(0x00, 0x48, 0xB6),
    [Color.FromArgb(0x91, 0x6D, 0x24)] = Color.FromArgb(0x00, 0x48, 0x91),
    [Color.FromArgb(0x6D, 0x48, 0x00)] = Color.FromArgb(0x00, 0x24, 0x6D),
    [Color.FromArgb(0x48, 0x24, 0x24)] = Color.FromArgb(0x00, 0x24, 0x48),
    [Color.FromArgb(0x24, 0x00, 0x00)] = Color.FromArgb(0x00, 0x00, 0x24),
};
 
using (Bitmap bitmap = new Bitmap("Пример.png"))
using (var bl = new BitmapLocker(bitmap))
{
    for (int i = 0; i < bl.Width; i++)
    {
        for (int j = 0; j < bl.Height; j++)
        {
            Color c = bl.GetPixel(i, j);
 
            if (colorReplacements.TryGetValue(c, out var nc))
                bl.SetPixel(i, j, nc);
        }
    }
    bitmap.Save("Пример2.png");
}
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,904
08.08.2020, 16:24  [ТС]
Да цвета не те. Надо разбираться почему большинство цветов не совпадают.
0
 Аватар для Toros1992
899 / 554 / 275
Регистрация: 26.11.2015
Сообщений: 1,762
Записей в блоге: 2
08.08.2020, 16:24
Alexandr_7, не может быть, чтобы 2 секунды. Сам использовал LockBits. Очень быстро.
Значит у вас что-то ещё тормозило
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,904
09.08.2020, 13:22  [ТС]
Разобрался с палитрой. Вот код:
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
private void button1_Click(object sender, EventArgs e)
        {
            Dictionary<Rgba32, Rgba32> colorReplacements = new Dictionary<Rgba32, Rgba32>
            {
                [new Rgba32(252,216,144)] = new Rgba32(0, 72, 255),
                [new Rgba32(216,180,108)] = new Rgba32(0, 72, 218),
                [new Rgba32(180,144,72)] = new Rgba32(0, 72, 182),
                [new Rgba32(144,108,36)] = new Rgba32(0, 72, 145),
                [new Rgba32(108,72,0)] = new Rgba32(0, 36, 109),
                [new Rgba32(72, 36, 36)] = new Rgba32(0, 36, 72),
                [new Rgba32(36, 0, 0)] = new Rgba32(0, 0, 36)
            };
 
            using (SixLabors.ImageSharp.Image<Rgba32> img = SixLabors.ImageSharp.Image.Load<Rgba32>("Пример.png"))
            {
                for (int y = 0; y < img.Height; y++)
                {
                    Span<Rgba32> pixelRowSpan = img.GetPixelRowSpan(y);
                    for (int x = 0; x < img.Width; x++)
                    {
                        if (colorReplacements.TryGetValue(pixelRowSpan[x], out var cn))
                            pixelRowSpan[x] = cn;
                    }
                }
 
                img.SaveAsPng("Пример2.png");
            }
 
            var btmp = new Bitmap("Пример2.png");
 
            pictureBox1.Image = btmp;
        }
Вот результат.
https://youtu.be/n9C0ZX79Ljw
Да. Намного быстрее чем SetPixel и GetPixel но все равно это не мгновенно. Вероятно из за сохранения и загрузки. А можно ли передать на прямую или может у SixLabors.ImageSharp имеется свой PictureBox на WinForms?
Да и не надо мне сохранять измененный результат. Это по сути просто графическая оболочка чисел. На самом деле все результаты храняться в ASM файле.
Ну в данном случае это пример. Я теперь примеры делаю прежде чем выносить в реальный код.
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,576
09.08.2020, 13:36
Конвертировать в Bitmap можно например так
C#
1
2
3
4
5
6
7
8
9
10
11
12
        public static System.Drawing.Bitmap ToBitmap<TPixel>(Image<TPixel> image) where TPixel : unmanaged, IPixel<TPixel>
        {
            using (var memoryStream = new MemoryStream())
            {
                var imageEncoder = image.GetConfiguration().ImageFormatsManager.FindEncoder(PngFormat.Instance);
                image.Save(memoryStream, imageEncoder);
 
                memoryStream.Seek(0, SeekOrigin.Begin);
 
                return new System.Drawing.Bitmap(memoryStream);
            }
        }
Ну и вариант выше с BitmapLocker работает по моему с примерно такой же скоростью, но там не нужно ничего конвертировать т.к. уже есть Bitmap...
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,904
09.08.2020, 16:12  [ТС]
А где находится BitmapLocker или его нету в Net Core 3.1?
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,904
09.08.2020, 16:20  [ТС]
Цитата Сообщение от Someone007 Посмотреть сообщение
Конвертировать в Bitmap можно например так
А на счет этого кода то он не работает
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,576
09.08.2020, 16:31
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
А где находится BitmapLocker или его нету в Net Core 3.1?
На github же... https://github.com/vano-maisuradze/lock-bitmap

Цитата Сообщение от Alexandr_7 Посмотреть сообщение
А на счет этого кода то он не работает
C#
1
2
3
4
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.PixelFormats;
?
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,904
09.08.2020, 16:46  [ТС]
По моему BitmapLocker даже быстрее работает.
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,904
09.08.2020, 22:49  [ТС]
А что к слову лучше. Net Core или Net Framework или разницы особой нету? Имееться в виду WinForms
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,576
10.08.2020, 02:16
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
По моему BitmapLocker даже быстрее работает.
Возможно только за счет того что не нужна конвертация обратно в Bitmap для вашего случая.
Но просто загрузка/замена пикселей/сохранение у меня работает быстрее с ImageSharp, не намного но быстрее.
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
А что к слову лучше. Net Core или Net Framework или разницы особой нету? Имееться в виду WinForms
Я бы использовал .NET Core по многим причинам:
- множество оптимизаций рантайма в плане улучшения производительности
- доступность новых API (те же Span<T> перегрузки например), которых нет в .NET Framework
- нормальная поддержка последних версий C# (.NET Framework C# 8 и выше не поддерживает)
- задел на будущее (.NET Framework больше на развивается и что-то писать на нем, особенно новое не имеет смысла)
- возможность поставлять приложение вместе с runtime'ом (который к тому же не требует установки в отличии от .NET Framework)

И это далеко не полный список...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
10.08.2020, 02:16

Различие цветов однотонной картинки
Проблема такая background задан png картинкой, а снизу на after полоска такого же цвета, но просто background: color; Почему то на...

Уменьшить количество цветов картинки!
Добрые люди, как можно решить задачу! во всем интернете только одна страница с трезвым ответом, но этого мало ...

Обрезка списка цветов из картинки
День добрый. Стоит следующая задача, есть картинка, в ней кроме whitespace нужно удалить еще 215 цветов, которые идут в разнобой до...

Замена цветов в картинке
Сразу извиняюсь за столь банальный вопрос. Суть в следующем: имеется файл формата .png в котором надо черный цвет заменить на белый....

Замена цветов на картинке
Здравствуйте. Вот код покраски сейчасный: void SetPaletteExample(string aNewPalette) { Bitmap GX_BufExample =...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Программное добавление префикса в нумерацию документов
Maks 27.10.2026
Задача: Программно добавить префикс в нумерацию документов в самописной конфигурации на БСП (помощь начинающему коллеге). Решение: В модуле объекта документа размещен следующий код: Процедура. . .
После закрытия оутлука продолжает висеть процесс в диспетчере задач
Maks 27.10.2026
С недавнего времени в продакшене возникла проблема: при закрытии оутлука в диспетчере задач продолжал висеть процесс outlook. exe. Проблема возникла после установки MS Office 2021 LTSC на машинах, под. . .
Baragoz - DPS/HPS бот для WoW 3.3.5a, многоязычный
AmbA 26.10.2026
Хотите ещё ботов? У меня есть один! А я пока отдохну от него. https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=12062&stc=1&d=1793007952 Инструкция внутри. https:/ / youtu. be/ VpfFZSUDGnQ. . .
Особенности gif сгенерированных в Си
russiannick 21.10.2026
Рассмотрим генерацию gif файлов, которые в Си имеют свои особенности. Gif представляет собой графический формат популярный в интернете. Посмотрим на палитру. Gif файл сгенерированный в си отличается. . .
FPS контроллер с анимированными Y-Bot и 3D-звуком miniaudio (Box3D, Recast, BehaviorTree.CPP, ozz-animation, ImGui, OpenGL и SDL3)
8Observer8 18.10.2026
Содержание блога | English Version Полное мультиплатформенное руководство по стартовому проекту с FPS-контроллером игрока, анимированными роботами Y-Bot с 4-слойным блендингом, 3D-физикой Box3D,. . .
Локальный http сервер
Argus19 17.10.2026
Локальный http сервер На работе, на двух локальных компьютерах круглосуточно работают программы опроса приборов с записью в книги Excel,которые раз в сутки записываются на сервер компании. Т. к. . . .
Копировать Windows на новый диск на UEFI
damix 17.10.2026
https:/ / uriesk. wordpress. com/ 2016/ 11/ 01/ move-window-10-to-ssd-on-a-uefi-dualboot-system-with-basic-linux-tools/ TL DR Вставляем диск, а старый подключаем через переходник, грузимся с лайва. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru