Форум программистов, компьютерный форум, киберфорум
Наши страницы
C++/CLI Windows Forms
Войти
Регистрация
Восстановить пароль
 
skident
23 / 23 / 6
Регистрация: 11.12.2011
Сообщений: 300
#1

Исказить изображение - C++/CLI WinForms

03.03.2013, 21:24. Просмотров 924. Ответов 16
Метки нет (Все метки)

Есть ли стандартные visual c++ функции для искажения рисунка?

Добавлено через 5 минут
Есть такие прикидки.
Беру с рисунка квадрат, например с длиной стороны 3. Пишу данный квадрат в массив. И вот мне надо как-то заменить элементы массива по кругу. Не на 90 градусов развернуть массив, а сделать, что-то типа такого

исходный:
1 2 3
4 5 6
7 8 9

после обработки
4 1 2
7 5 3
8 9 6

лучше конечно, если бы можно было вывести какую-то закономерность и найти элементы массива которые находятся на грани вписанного в квадрат круга и крутить их, но я уж вообще не допру как
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.03.2013, 21:24
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Исказить изображение (C++/CLI WinForms):

Фоновое изображение формы
Подскажите пожалуйста, как программно поменять фоновое изображение формы...

Перевернуть изображение в windows forms
Доброго времени суток. У меня в задаче, windows forms подается входной файл с...

Как загрузить изображение в PictureBox?
Задача по нажатию на кнопку открыть файл(картинку и вывести ее в pictureBox1)....

Как закрепить нарисованое изображение на PictureBox?
Color ^col = gcnew Color(); Pen ^mybrysh = gcnew Pen(col->Yellow); Graphics...

Изображение или анимация из графических примитивов
Может у кого завалялось любое изображение(домики, флажки, машинки, что угодно)...

16
ValeryS
Модератор
7124 / 5392 / 669
Регистрация: 14.02.2011
Сообщений: 18,201
03.03.2013, 23:01 #2
Цитата Сообщение от skident Посмотреть сообщение
Беру с рисунка квадрат, например с длиной стороны 3. Пишу данный квадрат в массив. И вот мне надо как-то заменить элементы массива по кругу. Не на 90 градусов развернуть массив, а сделать, что-то типа такого
матрицы, не?
0
skident
23 / 23 / 6
Регистрация: 11.12.2011
Сообщений: 300
04.03.2013, 00:48  [ТС] #3
ну по сути да, это будет матрица.
0
ValeryS
Модератор
7124 / 5392 / 669
Регистрация: 14.02.2011
Сообщений: 18,201
04.03.2013, 00:53 #4
любая обработка изображений сводится к работе с матрицами
посмотри
http://vnuki.org/library/book/457037
там это хорошо описано
0
skident
23 / 23 / 6
Регистрация: 11.12.2011
Сообщений: 300
04.03.2013, 01:44  [ТС] #5
спасибо за книгу, пытаюсь скачать.

Тут возникла проблема с копированием самого квадрата пикселей. То есть у меня есть 2 координаты x, y и собственно половина длинны стороны. А вот как перекопировать данный кусок на новый битмап не пойму. Попробовал создать массив Color, но компилятор сказал, что нельзя такой массив делать. Пробую CopyRect, тоже не получается. может я что-то не так делаю?!
0
ValeryS
Модератор
7124 / 5392 / 669
Регистрация: 14.02.2011
Сообщений: 18,201
04.03.2013, 01:54 #6
Цитата Сообщение от skident Посмотреть сообщение
Попробовал создать массив Color, но компилятор сказал, что нельзя такой массив делать.
а как делаешь?
надо так
C++
1
COLORREF rgbArray[100][100];

Цитата Сообщение от skident Посмотреть сообщение
Тут возникла проблема с копированием самого квадрата пикселей.
для начала попробуй GetPixel считать пиксел
и SetPixel установить пиксел
это надежные но тормознутые функции
когда разберешься то
BitBlt,memcpy
0
skident
23 / 23 / 6
Регистрация: 11.12.2011
Сообщений: 300
04.03.2013, 02:11  [ТС] #7
SetPixe(), GetPixel() как раз и пользуюсь. Мне сейчас на скорость особо роли не играет.
А вот с COLORREF ошибка
C++
1
Ошибка  1   error C2065: COLORREF: необъявленный идентификатор  d:\multimedia\visual studio 2010\projects\balloon\balloon\Form1.h   207
И книга, что-то никак не скачивается. Не мой день)
0
ValeryS
Модератор
7124 / 5392 / 669
Регистрация: 14.02.2011
Сообщений: 18,201
04.03.2013, 02:17 #8
Цитата Сообщение от skident Посмотреть сообщение
Form1.h * 207
стоп
ты в CLI пишешь?
1
skident
23 / 23 / 6
Регистрация: 11.12.2011
Сообщений: 300
04.03.2013, 02:25  [ТС] #9
Походу да. Решил копирование так:

C++
1
array<Color,2>^ myPicColors = gcnew array<Color,2>(Wdth,Hgh);
0
ValeryS
Модератор
7124 / 5392 / 669
Регистрация: 14.02.2011
Сообщений: 18,201
04.03.2013, 02:27 #10
Цитата Сообщение от skident Посмотреть сообщение
Походу да.
ну тогда я тебе не помощник
0
skident
23 / 23 / 6
Регистрация: 11.12.2011
Сообщений: 300
04.03.2013, 02:38  [ТС] #11
А какие есть по проще способы. Я если честно, то смутно понимаю, что такое CLI. Дело в том, что никогда не кодил на Visual C++, а тут поставили задачу. Вот сижу и в большинстве гуглю и на форуме спрашиваю, то что совсем уже найти не могу.

Добавлено через 4 минуты
Задачка вроде бы не сложная. Реализовать визуальный эффект от взрыва на visual c++ вид сверху. То есть надо участок рисунка как-то исказить или применить какой-то фильтр, без применения директ икс и опенГЛ. Но вот как сел делать, так на каждом шагу ступор...
0
ValeryS
Модератор
7124 / 5392 / 669
Регистрация: 14.02.2011
Сообщений: 18,201
04.03.2013, 02:41 #12
Цитата Сообщение от skident Посмотреть сообщение
А какие есть по проще способы.
Ну не знаю насколько проще
но я пишу на MFC или WinApi

Цитата Сообщение от skident Посмотреть сообщение
без применения директ икс и опенГЛ
Это обязательное ограничение?
просто директ икс заточен на обработку изображений
0
skident
23 / 23 / 6
Регистрация: 11.12.2011
Сообщений: 300
04.03.2013, 03:14  [ТС] #13
Да, именно фишка в том, чтобы не использовать мощных библиотек которые под это заточены.

Ну вот у меня выходит основной затык в последовательной обработке куска рисунка. То есть если это взрыв, то значит будет радиус взрыва, а значит надо как-то как минимум немного перекрасить пиксели данного круга, но так как это анимация надо сделать это как-то динамически и наглядно.

То есть подкрасить маленький кружок, потом кружок чуть больше и так до максимально указаного радиуса.

Была идея рисовать черный круг определенного радиуса. Потом вырезать квадрат пикселей с вписанным ранее кругом. Потом проверять все пиксели и если у пикселя есть сверху, снизу, справа и слева черные пиксели, то как-то подкрашивать его (например затемнить можно). А потом данный временный массив запихнуть назад в исходный, а исходный прорисовать по новой.

Могут конечно быть проблемы с тем, что на рисунке скорее всего могут присутствовать свои черные пиксели, но это думаю не очень страшно.

А вот с этим кругом даже не знаю - адекватная ли идея или полный бред

Добавлено через 19 минут
Кстати очень интересная книга. Спасибо большое за ссылочку и конечно же за помощь.
0
MrCold
859 / 757 / 174
Регистрация: 11.01.2012
Сообщений: 1,942
04.03.2013, 16:03 #14
Цитата Сообщение от skident Посмотреть сообщение
крутить их,
Graphics.RotateTransform
Graphics.TranslateTransform
Image.RotateFlip

Добавлено через 3 минуты
Цитата Сообщение от skident Посмотреть сообщение
Беру с рисунка квадрат
А ни легче анимацию сделать, перебирая набор спрайтов .
Или GIF взрыва в форму вставить ?

Добавлено через 28 минут
Мысль такая :
Создать массив частиц в одной стартовой точке
И в рандомном направлении раскидать
По мере движения увеличивать размер и уменьшать яркость частиц.

Вот, что -то попытался, на взрыв может не тянет
ну лучше чем ни чего
Код можно просто скопипастить ничего не добавляя на форму :
( Вместо Explosion , во второй строке вставьте имя своего проекта
Form1.h
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
173
174
175
176
#pragma once
 
namespace Explosion {
 
    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;
 
    /// <summary>
    /// Сводка для Form1
    /// </summary>
    public ref class Form1 : public System::Windows::Forms::Form
    {
    public:
        Form1(void)
        {
            InitializeComponent();
            //
            //TODO: добавьте код конструктора
            //
            
            gr = this->CreateGraphics();
            listData = nullptr;
            rand = gcnew Random();
 
            this->BackColor = System::Drawing::Color::Navy;
            this->DoubleBuffered = true;
            this->FormClosing += gcnew System::Windows::Forms::FormClosingEventHandler(this, &Form1::Form1_FormClosing);
            this->button1 = (gcnew System::Windows::Forms::Button());
            this->button1->Location = System::Drawing::Point(190, 218);
            this->button1->Size = System::Drawing::Size(75, 23);
            this->button1->Text = L"Explosion";
            this->button1->UseVisualStyleBackColor = true;
            this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);
            this->Controls->Add(this->button1);
            
 
        }
    private: System::Windows::Forms::Button^  button1;
    private: System::Drawing::Graphics^ gr;
 
   
    public: ref class Particle
            {
 
            public: Particle(float posX, float posY, float sX, float sY, float sizeSide)
                {
                    positionX = posX;
                    positionY = posY;
                    speedX = sX;
                    speedY = sY;
                    startSizeSide = sizeSide;
                    alpha = 255;
 
                    this->timer = gcnew System::Windows::Forms::Timer();
                    this->timer->Enabled = true;
                    this->timer->Interval = 1;
                    this->timer->Tick += gcnew System::EventHandler(this,&Particle::timer_Tick);
                 }
 
                        float positionX, positionY;
                        float speedX, speedY;
                        float startSizeSide;
                        int alpha;
            
                        
            private: System::Windows::Forms::Timer^ timer;
            
 
            private: void timer_Tick(Object^ sender, EventArgs^ e)
                        {
                            positionX +=  speedX;
                            positionY +=  speedY;
                            if ( startSizeSide < 15)
                            startSizeSide += 0.2f;
                            if (alpha > 10)
                                alpha -= (int)startSizeSide / 2;
                        }
                    
            };
 
    private: System::Collections::Generic::List<Particle^>^ listData;
 
    private: Random^ rand;
 
            void CreateParticles()
            {
 
                listData = gcnew System::Collections::Generic::List<Particle^>();
                for (int i = 0; i < 100; i++)
                {
                    Particle^ data = gcnew Particle
                        (
                            (float)this->Width / 2,
                            (float)this->Width / 3, 
                            rand->Next(-3, 3) * (float)rand->NextDouble(),
                            (float)rand->Next(-3, 3) * (float)rand->NextDouble(),
                            (float)rand->Next(3)
                        );
                    listData->Add(data);
                }
 
            }
 
            void Draw()
            {
                if (listData != nullptr)
                {
                    for (int i = 0; i < listData->Count; i++)
                    {
                        Color color = Color::FromArgb(listData[i]->alpha, Color::Orange);
                        if (listData[i]->alpha < 15)
                            color = this->BackColor;
                        gr->FillEllipse(gcnew SolidBrush(color), listData[i]->positionX, listData[i]->positionY, listData[i]->startSizeSide, listData[i]->startSizeSide);
                    }
 
                }
            }
 
    private: void Form1_FormClosing(Object^ sender, FormClosingEventArgs^ e)
        {
            Environment::Exit(0);
        }
 
     private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
 
                CreateParticles();
                int i = 0;
                while (i < 80)
                {
                    this->BackColor = Color::MidnightBlue;
                    Draw();
                    this->Invalidate();
                    Application::DoEvents();
                    i++;
                }
                this->BackColor = Color::Navy;
 
    }
    protected:
        /// <summary>
        /// Освободить все используемые ресурсы.
        /// </summary>
        ~Form1()
        {
            if (components)
            {
                delete components;
            }
        }
 
    private:
        /// <summary>
        /// Требуется переменная конструктора.
        /// </summary>
        System::ComponentModel::Container ^components;
 
#pragma region Windows Form Designer generated code
        /// <summary>
        /// Обязательный метод для поддержки конструктора - не изменяйте
        /// содержимое данного метода при помощи редактора кода.
        /// </summary>
        void InitializeComponent(void)
        {
            this->components = gcnew System::ComponentModel::Container();
            this->Size = System::Drawing::Size(300,300);
            this->Text = L"Form1";
            this->Padding = System::Windows::Forms::Padding(0);
            this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
        }
#pragma endregion
    };
}
1
skident
23 / 23 / 6
Регистрация: 11.12.2011
Сообщений: 300
05.03.2013, 07:43  [ТС] #15
MrCold, сейчас пробую написать на win32 API, так как заметил, что меньше кода которого я вовсе не понимаю.

По поводу сделать сделать анимацию взрыва, я уже думал. То есть запилить объект с анимацией и накладывать его на исходное изображение, а после на месте взрыва как-то немного подзатемнить рисунок.

Но тут есть пару нюансов:
1. нужно сделать так, чтобы пользователь мог настраивать радиус взрыва
2. ну и как собственно накладывать анимацию поверх какой-то точки на рисунке я тоже не знаю

Спасибо за код, посмотрю как реализовали.

Добавлено через 10 минут
Интересная анимация

Добавлено через 12 часов 19 минут
В общем кое-что написал. Проект находится тут . Если кто решится просмотреть код, то пишите, что не так.
0
MrCold
859 / 757 / 174
Регистрация: 11.01.2012
Сообщений: 1,942
05.03.2013, 16:38 #16
C++
1
2
3
4
5
unsigned char red = 0;
//проверка не ушли ли цвета в минус
if ( red < 0 ) red = 0;
if ( green < 0 ) green = 0;
if ( blue < 0 ) blue = 0;
red = 255 red += 1
получим red == 0

red = 0
red -1
получим red == 255

Добавлено через 10 минут
Цитата Сообщение от skident Посмотреть сообщение
то пишите, что не так.
Не понятно при чем тут взрыв , искажение изображения ?
Мне кажется у вас не то совсем .
Надеюсь, что я просто не в теме .
Возможно (мне подсказали )
в задании речь идет о 2 - мерной математической модели взрыва
Трудно судить когда не понимаешь что к чему
0
skident
23 / 23 / 6
Регистрация: 11.12.2011
Сообщений: 300
05.03.2013, 16:51  [ТС] #17
Ну это выходит не взрыв, а ударная волна. То есть самого взрыва не происходит, а есть какой-то эпицентр и от него идет волна. Да, вполне может быть, что совсем не то написал. Но думаю в скором времени я узнаю точно, что к чему и отпишусь тут если кому-то это будет интересно
1
05.03.2013, 16:51
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.03.2013, 16:51
Привет! Вот еще темы с решениями:

Как исказить картинку таким образом
Как с помощью PHP (imagimagick) исказить так картинку?

На небольшом логотипе создать текст, а потом его исказить, как в титрах звёздных войн
Добрый вечер! Передо мной стоит задача: на небольшом логотипе создать текст, а...

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

Подскажите, как сделать в html, чтобы изображение накладывалось на другое изображение?
Нужно, чтобы изображение накладывалось на другое изображение, а другое...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru