Аватар для SkyDen
1 / 1 / 0
Регистрация: 09.05.2017
Сообщений: 26

Как ускорить отрисовку изображения?

31.10.2017, 14:08. Показов 3499. Ответов 6

Студворк — интернет-сервис помощи студентам
Доброго времени суток. Столкнулся с такой проблемой: Необходимо загрузить инвертированное изображение, обратить цвета (сделать нормальным), и вывести это изображение. Я вывожу его в Picture Box. Для решения этой задачи я создал двумерный массив, который считывает пиксель изображения из загруженной картинки и инвертирует, сохраняя в другом массиве :
C#
1
2
3
4
5
6
7
8
9
10
11
12
Bitmap b1 = new Bitmap(bitmapFilePath);
Graphics drawing;
drawing = pictureBox1.CreateGraphics();
int hight = b1.Height;
int width = b1.Width;
Color[,] colorMatrixInv = new Color[width, hight];
Color[,] colorMatrix = new Color[width, hight];
 for (int j = 0; j < hight; j++)
    {
   colorMatrix[i, j] = b1.GetPixel(i, j);
   colorMatrixInv[i, j] = Color.FromArgb(colorMatrix[i, j].A, 0xFF - colorMatrix[i, j].R, 0xFF - colorMatrix[i, j].G, 0xFF - colorMatrix[i,j].B);
     }
После осуществляется вывод инвертированного изображения:
C#
1
2
3
4
5
6
7
 for (int i = 0; i < hight; i++)
            {
                for (int j = 0; j < width; j++)
                {
                        System.Drawing.SolidBrush myBrush = new System.Drawing.SolidBrush(colorMatrixInv[j, i]);
                        drawing.FillRectangle(myBrush, j, i, 1, 1);                                
            }
Но проблема в том, что изображение вырисовываться медленно. Дома на мощном железе, вырисовывается более менее шустро, но необходимо, чтобы оно выводилось сразу. В университете на тамошних компьютерах все отрисовываеться очень медленно. Пробовал отрисовывать изображение в созданную bitmap и выводить его сразу в picturebox,но вывод осуществлялся с такой же задержкой, что отрисовка попиксельно. Слышал про метод Двойной буферизации, но не как не смог его применить.
Подскажите, как решить эту проблему?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
31.10.2017, 14:08
Ответы с готовыми решениями:

Как ускорить отрисовку примитивов на PictureBox'e
Есть следующая проблема. По движению мыши на Bitmap'e рисую сплошную линию(с кистью в виде эллипсов). Затем переношу изображение на...

Как ускорить отрисовку изображения на PictureBox
Может кто знает как можно ускорить отрисовку загруженного изображения в PictureBox, (изображение довольно таки большое 1500х1500 и выше)...

Как ускорить отрисовку контролов на форме?
Програмно создаю на форме много контролов - кнопок (&gt;200) и возникают такие проблемы: 1. Контролы появляются не все сразу, а, как бы,...

6
677 / 479 / 216
Регистрация: 06.09.2013
Сообщений: 1,312
31.10.2017, 14:24
SkyDen, unsafe mode и адресная арифметика
0
 Аватар для SkyDen
1 / 1 / 0
Регистрация: 09.05.2017
Сообщений: 26
31.10.2017, 14:35  [ТС]
А не могли бы чуть чуть подробнее рассказать об этом методе?
0
1741 / 913 / 480
Регистрация: 05.12.2013
Сообщений: 3,074
31.10.2017, 15:04
Цитата Сообщение от SkyDen Посмотреть сообщение
Слышал про метод Двойной буферизации, но не как не смог его применить.
А это что значит? У формы есть свойство DoubleBuffered.
0
TheGreatCornholio
 Аватар для Woldemar89
1255 / 733 / 285
Регистрация: 30.07.2015
Сообщений: 2,408
31.10.2017, 15:42
Глянь тут и тут для правильной работы с контролами\моделью
0
315 / 244 / 149
Регистрация: 03.10.2017
Сообщений: 886
Записей в блоге: 1
31.10.2017, 15:50
Можно использовать Bitmap. Сначала нанести на него, а потом уже в pictureBox Вывести этот Bitmap
0
 Аватар для SkyDen
1 / 1 / 0
Регистрация: 09.05.2017
Сообщений: 26
31.10.2017, 18:03  [ТС]
Цитата Сообщение от Masson1848 Посмотреть сообщение
Можно использовать Bitmap. Сначала нанести на него, а потом уже в pictureBox Вывести этот Bitmap
Я так пробовал. Изображение в PictureBox выводиться с задержкой, равной той, что была бы при отрисовке по пиксельно. Я когда в цикле последовательность картинок вывожу задержка идёт.

Добавлено через 34 секунды
Попробовал вариант который предложил Woldemar89, изображение выводиться как надо, но в цикле почему то не меняются - всё время отображается одна картинка. Пробовал в конце цикла делать pbSource.Image = null, но тогда изображение не выводиться совсем.
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
161
162
163
164
165
166
167
168
169
170
171
172
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Net;
using System.Windows.Forms;
using System.Threading;
 
namespace WindowsFormsApp3
{
 
     public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
 
            for (int n = 1; n < 8; n++)
            {
                var img = (Bitmap)Image.FromFile(@"C:\res\" +n+".bmp");
                var pbSource = new PictureBox { Parent = this, SizeMode = PictureBoxSizeMode.Zoom, Width = 200, Height = 200 };
                pbSource.Image = imageOut(img);
            }
 
        }
 
        private Image imageOut(Bitmap img)
        {
            var res = (Bitmap)img.Clone();
            using (var wr = new ImageWrapper(res))
                foreach (var p in wr)
                {
                    var c = wr[p];
                    wr.SetPixel(p, 0xFF-c.R, 0xFF-c.G , 0xFF-c.B );
                }
            return res;
        }
    }
    
    public class ImageWrapper : IDisposable, IEnumerable<Point>
    {
        /// <summary>
        /// Ширина изображения
        /// </summary>
        public int Width { get; private set; }
        /// <summary>
        /// Высота изображения
        /// </summary>
        public int Height { get; private set; }
        /// <summary>
        /// Цвет по-умолачнию (используется при выходе координат за пределы изображения)
        /// </summary>
        public Color DefaultColor { get; set; }
 
        private byte[] data;//буфер исходного изображения
        private byte[] outData;//выходной буфер
        private int stride;
        private BitmapData bmpData;
        private Bitmap bmp;
 
        /// <summary>
        /// Создание обертки поверх bitmap.
        /// </summary>
        /// <param name="copySourceToOutput">Копирует исходное изображение в выходной буфер</param>
        public ImageWrapper(Bitmap bmp, bool copySourceToOutput = false)
        {
            Width = bmp.Width;
            Height = bmp.Height;
            this.bmp = bmp;
 
            bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
            stride = bmpData.Stride;
 
            data = new byte[stride * Height];
            System.Runtime.InteropServices.Marshal.Copy(bmpData.Scan0, data, 0, data.Length);
 
            outData = copySourceToOutput ? (byte[])data.Clone() : new byte[stride * Height];
        }
 
        /// <summary>
        /// Возвращает пиксел из исходнго изображения.
        /// Либо заносит пиксел в выходной буфер.
        /// </summary>
        public Color this[int x, int y]
        {
            get
            {
                var i = GetIndex(x, y);
                return i < 0 ? DefaultColor : Color.FromArgb(data[i + 3], data[i + 2], data[i + 1], data[i]);
            }
 
            set
            {
                var i = GetIndex(x, y);
                if (i >= 0)
                {
                    outData[i] = value.B;
                    outData[i + 1] = value.G;
                    outData[i + 2] = value.R;
                    outData[i + 3] = value.A;
                };
            }
        }
 
        /// <summary>
        /// Возвращает пиксел из исходнго изображения.
        /// Либо заносит пиксел в выходной буфер.
        /// </summary>
        public Color this[Point p]
        {
            get { return this[p.X, p.Y]; }
            set { this[p.X, p.Y] = value; }
        }
 
        /// <summary>
        /// Заносит в выходной буфер значение цвета, заданные в double.
        /// Допускает выход double за пределы 0-255.
        /// </summary>
        public void SetPixel(Point p, double r, double g, double b)
        {
            if (r < 0) r = 0;
            if (r >= 256) r = 255;
            if (g < 0) g = 0;
            if (g >= 256) g = 255;
            if (b < 0) b = 0;
            if (b >= 256) b = 255;
 
            this[p.X, p.Y] = Color.FromArgb((int)r, (int)g, (int)b);
        }
 
        int GetIndex(int x, int y)
        {
            return (x < 0 || x >= Width || y < 0 || y >= Height) ? -1 : x * 4 + y * stride;
        }
 
        /// <summary>
        /// Заносит в bitmap выходной буфер и снимает лок.
        /// Этот метод обязателен к исполнению (либо явно, лмбо через using)
        /// </summary>
        public void Dispose()
        {
            System.Runtime.InteropServices.Marshal.Copy(outData, 0, bmpData.Scan0, outData.Length);
            bmp.UnlockBits(bmpData);
        }
 
        /// <summary>
        /// Перечисление всех точек изображения
        /// </summary>
        public IEnumerator<Point> GetEnumerator()
        {
            for (int y = 0; y < Height; y++)
                for (int x = 0; x < Width; x++)
                    yield return new Point(x, y);
        }
 
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
 
        /// <summary>
        /// Меняет местами входной и выходной буферы
        /// </summary>
        public void SwapBuffers()
        {
            var temp = data;
            data = outData;
            outData = temp;
        }
    }
 
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
31.10.2017, 18:03
Помогаю со студенческими работами здесь

Как ускорить вывод изображения?
Здравствуйте уважаемые программисты! Вот я пишу игровой 2D движок на C++ directx9 и то, что у меня получилось сравниваю с американским 2D...

Как ускорить прорисовку изображения?
Добрый день! Решил написать небольшой просмотрщик изображений на WPF, и столкнулся с такой проблемой, когда загружаю достаточно большое...

Ускорить вывод изображения в JLabel
Подскажите, пожалуйста, можно ли каким-то образом ускорить вывод изображения в JLabel. Использую двойную буферизацию, как off-screen буфер...

Преобразование изображения: ускорить работу кода
Добрый. Как можно ускорить следующий код? Мне необходимо конвертировать определенный цвет в пространстве RGB в пространство LAB. Я хочу...

Как правильно организовать отрисовку 2D графики?
Планируется сделать векторный 2D редактор, с количеством примитивов (не полигонов) около 300 000 Градиентов не будет, только сплошные...


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

Новые блоги и статьи
Валидация и контроль данных табличной части документа перед записью
Maks 22.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в КА2. Задача: контроль и валидация данных табличной части документа перед записью с учетом регламента компании. . .
Отчёт о затраченных материалах за определенный период с макетом печатной формы
Maks 21.04.2026
Отчёт из решения ниже размещён в конфигурации КА2. Задача: разработка отчёта по затраченным материалам за определённый период, с возможностью вывода печатной формы отчёта с шапкой и подвалом. В. . .
Отчёт о спецтехнике находящейся в ремонте
Maks 20.04.2026
Отчёт из решения ниже размещен в конфигурации КА2. Задача: отобразить спецтехнику, которая на данный момент находится в ремонте. Есть нетиповой документ "Заявка на ремонт спецтехники" который. . .
Памятка для бота и "визитка" для читателей "Semantic Universe Layer (Слой семантической вселенной)"
Hrethgir 19.04.2026
Сгенерировано для краткого описания по случаю сборки и компиляции скелета серверного приложения. И пусть после этого скажут, что статьи сгенерированные AI - туфта и не интересно. И это не реклама -. . .
Запрет удаления строк ТЧ документа при определённом условии
Maks 19.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "Аккумуляторы", разработанного в конфигурации КА2. У данного документа есть ТЧ, в которой в зависимости от прав доступа. . .
Модель заражения группы наркоманов
alhaos 17.04.2026
Условия задачи сформулированы тут Суть: - Группа наркоманов из 10 человек. - Только один инфицирован ВИЧ. - Колются одной иглой. - Колются раз в день. - Колются последовательно через. . .
Мысли в слух. Про "навсегда".
kumehtar 16.04.2026
Подумалось тут, что наверное очень глупо использовать во всяких своих установках понятие "навсегда". Это очень сильное понятие, и я только начинаю понимать край его смысла, не смотря на то что давно. . .
My Business CRM
MaGz GoLd 16.04.2026
Всем привет, недавно возникла потребность создать CRM, для личных нужд. Собственно программа предоставляет из себя базу данных клиентов, в которой можно фиксировать звонки, стадии сделки, а также. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru