Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.76/21: Рейтинг темы: голосов - 21, средняя оценка - 4.76
6 / 6 / 3
Регистрация: 03.01.2012
Сообщений: 449

Максимально эффективно нарисовать точку на форме

12.12.2012, 19:02. Показов 4511. Ответов 34
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
может быть было бы лучше использовать Directx?

опробовал способ:
C++
1
SetPixel(hdc,x,y,RGB(0,0,255));
жутко медлительный, вообще не подходит
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
12.12.2012, 19:02
Ответы с готовыми решениями:

Нарисовать точку в форме
Буду весьма благодарен за помощь. Нужно чтобы при нажатии кнопки, а затем и при нажатии по PictureBox появляется еще одна форма в...

Нарисовать и стереть точку на форме
Как нарисовать точку на форме и стереть(не стирая то, что под точкой)?

Как нарисовать точку в форме (простейший графический редактор)?
Решил сделать простейший графический редактор и встретился с проблемой, никак не могу реализовать карандаш по нормальному. В интернете...

34
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
12.12.2012, 19:12
Движение молнии точками рисовать собрался что ли? Зачем это все вообще?
Кстати, рисовать на форме напрямую, как правило, неэффективно по причине необходимости постоянной перерисовки.
1
6 / 6 / 3
Регистрация: 03.01.2012
Сообщений: 449
12.12.2012, 20:04  [ТС]
Цитата Сообщение от BRcr Посмотреть сообщение
Движение молнии точками рисовать собрался что ли? Зачем это все вообще?
Кстати, рисовать на форме напрямую, как правило, неэффективно по причине необходимости постоянной перерисовки.
надо сосчитать битмап изображение (загнав в массив), обработать и вывести его точечно на экран
а что посоветуете? рисовать на экране?
C++
1
GetDC(0);
~тоже самое время выполнения

есть ли способ быстрей?
есть ли смысл вникать в directx?
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
12.12.2012, 21:52
Посоветую, как обычно, рисовать на канве TBitmap, а потом уж выводить его, куда душе угодно. Причем использовать прямой доступ к графике с помощью свойства ScanLine. Увеличение скорости может быть более чем на порядок...
Рассмотри "официальный" пример по этому поводу:
Description

This example shows how to draw directly to a Bitmap. It loads a bitmap from a file and then copies it to another bitmap twice its size. Then the two bitmaps are displayed on the form canvas.

Code

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
#include <memory>       //For STL auto_ptr class
 
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  std::auto_ptr<Graphics::TBitmap> Bitmap(new Graphics::TBitmap);
  std::auto_ptr<Graphics::TBitmap> BigBitmap(new Graphics::TBitmap);
  TRGBTriple *ptr, *bigPtr;   // Use a (byte *) for pf8bit color.
  TPixelFormat pixForm, bigpixForm;
  try
  {
        Bitmap->LoadFromFile("../littlefac.bmp");
        pixForm = Bitmap->PixelFormat;
        bigpixForm  = BigBitmap->PixelFormat;
        Bitmap->PixelFormat = pf24bit;
        BigBitmap->PixelFormat = pf24bit;
        BigBitmap->Height = Bitmap->Height * 2;
        BigBitmap->Width = Bitmap->Width * 2;
        for (int y = 0; y < Bitmap->Height; y++)
    {
          ptr = reinterpret_cast<TRGBTriple *>(Bitmap->ScanLine[y]);
          for (int x = 0; x < Bitmap->Width; x++)
          {
                int bx = x * 2;
                int by = y * 2;
                bigPtr = reinterpret_cast<TRGBTriple *>(BigBitmap->ScanLine[by]);
                bigPtr[bx] = ptr[x];
                bigPtr[bx + 1] = ptr[x];
                bigPtr = reinterpret_cast<TRGBTriple *>(BigBitmap->ScanLine[by + 1]);
                bigPtr[bx] = ptr[x];
                bigPtr[bx + 1] = ptr[x];
          }
        }
        Canvas->Draw(0, 0, Bitmap.get());
        Canvas->Draw(200, 200, BigBitmap.get());
  }
  catch (...)
  {
    ShowMessage("Could not load or alter bitmap");
  }
}
- подумай, примени способы работы к своей задаче.
1
 Аватар для gumi250
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
13.12.2012, 00:10
кстати пример не оптимален по скорости, т.к.
C++
1
2
3
4
bigPtr = reinterpret_cast<TRGBTriple *>(BigBitmap->ScanLine[by]);
bigPtr[bx] = ptr[x];
bigPtr[bx + 1] = ptr[x];
bigPtr = reinterpret_cast<TRGBTriple *>(BigBitmap->ScanLine[by + 1]);
вызывается в цикле по х. А для скорости ScanLine должен вызываться только в цикле по y. И STL здесь тоже не нужен.
ТС лучше создать массив загрузить туда с помощью ScanLine битмап, обработать массив и потом вывести с помощью ScanLine на экран. Directx вам точно не нужен.
1
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
13.12.2012, 07:06
Простор для оптимизации есть всегда.
В нетах уже давненько болтается статейка от Pawel Glowacki по быстрой работе с TBitmap, все прозрачно, только она делфийская:
Delphi
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
type
  TColor2Grayscale = (
    c2gAverage,
    c2gLightness,
    c2gLuminosity
  );
 
  TBitmapAccess = (
    baScanLine,
    baPixels
  );
 
// ...
 
function RGBToGray(R, G, B: byte; cg: TColor2Grayscale = c2gLuminosity): byte;
begin
  case cg of
    c2gAverage:
      Result := (R + G + B) div 3;
 
    c2gLightness:
      Result := (max(R, G, B) + min(R, G, B)) div 2;
 
    c2gLuminosity:
      Result := round(0.2989*R + 0.5870*G + 0.1141*B); // coeffs from Matlab
 
    else
      raise Exception.Create('Unknown Color2Grayscale value');
  end;
end;
 
// ...
 
procedure ToGray(aBitmap: Graphics.TBitmap;
  cg: TColor2Grayscale = c2gLuminosity;
  ba: TBitmapAccess = baScanLine);
var w, h: integer; CurrRow, OffSet: integer;
  x: byte; pRed, pGreen, pBlue: PByte;
begin
  if ba = baPixels then
  begin
    if aBitmap <> nil then
      for h := 0 to aBitmap.Height - 1 do
        for w := 0 to aBitmap.Width - 1 do
          aBitmap.Canvas.Pixels[w,h] :=
            ColorToGray(aBitmap.Canvas.Pixels[w,h], cg);
  end
 
  else // ba = baScanLine
  begin
    if aBitmap.PixelFormat <> pf24bit then
      raise Exception.Create(
        'Not implemented. PixelFormat has to be "pf24bit"');
 
    CurrRow := Integer(aBitmap.ScanLine[0]);
    OffSet := Integer(aBitmap.ScanLine[1]) - CurrRow;
 
    for h := 0 to aBitmap.Height - 1 do
    begin
      for w := 0 to aBitmap.Width - 1 do
      begin
        pBlue  := pByte(CurrRow + w*3);
        pGreen := pByte(CurrRow + w*3 + 1);
        pRed   := pByte(CurrRow + w*3 + 2);
        x := RGBToGray(pRed^, pGreen^, pBlue^, cg);
        pBlue^  := x;
        pGreen^ := x;
        pRed^   := x;
      end;
      inc(CurrRow, OffSet);
    end;
  end
end;
2
 Аватар для gumi250
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
13.12.2012, 08:34
Ух ты спасибо, не знал что между началом строк в бмп одинаковое смещение.
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
13.12.2012, 10:04
Это ж bmp, просто массив, по три значения на пиксель...
0
 Аватар для gumi250
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
13.12.2012, 10:55
Что значит просто массив?
Если это непрерывный одномерный массив, то сканлайн вообще не нужен, за концом строки сразу идет начало следующей строки.
Если это двумерный массив, то в одном одномерном массиве хранятся адреса на начало других одномерных массивов (строк).
Что то бмп не похож не на один из этих вариантов.
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
13.12.2012, 11:02
Цитата Сообщение от gumi250 Посмотреть сообщение
Если это непрерывный одномерный массив,
Именно он и есть, scanline для удобства выборки по строкам.
0
 Аватар для gumi250
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
13.12.2012, 11:31
Не все так просто. В том примере который вы привели, там не идет выборка пикселей как в линейном массиве (нашел начало массива и погнал до конца). В примере считается смещение между началом строк, т.е. это смещение хоть и одинаково, но оно не равно длине строки. Возможно что то дописано в конец строки.
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
13.12.2012, 12:37
Цитата Сообщение от gumi250 Посмотреть сообщение
И STL здесь тоже не нужен.
А где там STL ?
Цитата Сообщение от BRcr Посмотреть сообщение
C++
1
ColorToGray(aBitmap.Canvas.Pixels[w,h], cg)
Ну тут через Pixels[][], а это тоже медленно...
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
13.12.2012, 12:46
Цитата Сообщение от Avazart Посмотреть сообщение
Ну тут через Pixels[][], а это тоже медленно...
там и со scanline есть режим, это как бы сравнение двух вариантов...
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
13.12.2012, 12:55
Delphi
1
2
3
4
5
function TCanvas.GetPixel(X, Y: Integer): TColor;
begin
  RequiredState([csHandleValid]);
  GetPixel := Windows.GetPixel(FHandle, X, Y);  // тут тоже не быстрая WinApi -ф-ция
end;
Ну собственно судя по коду исходников, можно еще быстрее через массив.

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function TBitmap.GetScanLine(Row: Integer): Pointer;
begin
  Changing(Self);
  with FImage.FDIB, dsbm, dsbmih do
  begin
    if (Row < 0) or (Row >= bmHeight) then
      InvalidOperation(@SScanLine);
    DIBNeeded;
    GDIFlush;
    if biHeight > 0 then  // bottom-up DIB
      Row := biHeight - Row - 1;
    Integer(Result) := Integer(bmBits) +
      Row * BytesPerScanline(biWidth, biBitCount, 32);
  end;
end;
0
 Аватар для gumi250
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
13.12.2012, 12:59
Цитата Сообщение от Avazart Посмотреть сообщение
А где там STL ?
сори, std
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
13.12.2012, 13:00
Ну а где?

Там как бы кроме умного указателя больше нету ничего.
0
 Аватар для gumi250
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
13.12.2012, 13:06
ну ведь можно без него, чего пример то усложнять
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
13.12.2012, 13:09
Цитата Сообщение от gumi250 Посмотреть сообщение
ну ведь можно без него, чего пример то усложнять
Скорее упрощать... во всех примерах подобного рода в справке используется auto_ptr<> что правильно для С++ ( хотя уже немного устарело учитывая стандарт.)
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
13.12.2012, 13:46
Цитата Сообщение от Avazart Посмотреть сообщение
Ну собственно судя по коду исходников, можно еще быстрее через массив.
В примере от Glowacki через массив работа и ведется, только без операторов разыменования по индексу, а просто элементарной инкрементацией указателя на текущую строку смещением строк относительно друг друга. Возможность оптимизации такого алгоритма выглядит, как по мне, так весьма сомнительно. Но простор, как я уже говорил...

А вот auto_ptr нормой я бы не назвал, его не стоит-таки использовать в местах, чувствительных к скорости, там любые лишние операции могут иметь значение.
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
13.12.2012, 13:52
Цитата Сообщение от BRcr Посмотреть сообщение
А вот auto_ptr нормой я бы не назвал, его не стоит-таки использовать в местах, чувствительных к скорости, там любые лишние операции могут иметь значение.
А при чем тут auto_ptr<> ?, там где важна скорость вообще не желательно каждый раз создавать/удалять объекты
но ведь в данном случае не так...
Зато безопасность важна... особенно актуально когда все делается в потоке при вероятности выброса исключения.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
13.12.2012, 13:52
Помогаю со студенческими работами здесь

Слияние отсортированных массивов максимально эффективно
Здравствуйте! По условию задачи есть два отсортированных по возрастанию массива. То есть сигнатура метода выглядит таким образом: ...

Как, максимально выгодно и эффективно, поставить на поток инсталяцию Windows ?
Я инженер, занимаюсь конечной сборкой и продажей мини ПК (SFF), но без ОС. Решил обратиться за советом ко всем Вам по следующему вопросу....

Как эффективно создать анимацию на форме
Сейчас делаю это обычным способом: сначала закрашиваю прямоугольником старый рисунок, а затем рисую сверху новый. Так я делал в С++...

Найти точку максимально удаленную от B
На плоскости имееться множество точек &lt;Ai&gt; и точка B. Каждая точка задана своими координатами найти среди точек &lt;Ai&gt;,точку...

Найти точку, максимально удалённую от центра координат
Дан массив X с координатами X точек координатной плоскости и массив Y с координатами y точек в координатной плоскости. Найти точку,...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Автоматическое создание документа при проведении другого документа
Maks 29.03.2026
Реализация из решения ниже выполнена на нетиповых документах, разработанных в конфигурации КА2. Есть нетиповой документ "ЗаявкаНаРемонтСпецтехники" и нетиповой документ "ПланированиеСпецтехники". В. . .
Настройка движения справочника по регистру сведений
Maks 29.03.2026
Решение ниже реализовано на примере нетипового справочника "ТарифыМобильнойСвязи" разработанного в конфигурации КА2, с целью учета корпоративной мобильной связи в коммерческом предприятии. . . .
Автозаполнение реквизита при выборе элемента справочника
Maks 27.03.2026
Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. При выборе "Спецтехники" (Тип Справочник. Спецтехника), заполняется. . .
Сумматор с применением элементов трёх состояний.
Hrethgir 26.03.2026
Тут. https:/ / fips. ru/ EGD/ ab3c85c8-836d-4866-871b-c2f0c5d77fbc Первый документ красиво выглядит, но без схемы. Это конечно не даёт никаких плюсов автору, но тем не менее. . . всё может быть. . .
Автозаполнение реквизитов при создании документа
Maks 26.03.2026
Программный код из решения ниже размещается в модуле объекта документа, в процедуре "ПриСозданииНаСервере". Алгоритм проверки заполнения реализован для исключения перезаписи значения реквизита,. . .
Команды формы и диалоговое окно
Maks 26.03.2026
1. Команда формы "ЗаполнитьЗапчасти". Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. В качестве источника данных. . .
Кому нужен AOT?
DevAlt 26.03.2026
Решил сделать простой ланчер Написал заготовку: dotnet new console --aot -o UrlHandler var items = args. Split(":"); var tag = items; var id = items; var executable = args;. . .
Отправка уведомления на почту при создании или изменении элементов справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной записи электронной. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru