Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 23.02.2011, 02:32   #1
Miha85193
Delphi, OpenGL API
Форумчанин
 
Аватар для Miha85193
 
Регистрация: 29.03.2010
Сообщений: 152
По умолчанию Чтение битмапа

Можно ли считать пиксели из битмапа, через указатель на их начало, не обращаясь при этом каждый раз к свойству ScanLine, или не обращаться к этому свойству вообще? Вот мой вариант.

Код:
procedure TForm1.DrawBitmap(Canvas: TCanvas);
var
  I, J: Integer;
  pLine: PByte;
  R, G, B: Byte;
begin
  for J := 0 to Bitmap.Height - 1 do
  begin
    pLine := Bitmap.ScanLine[J];
    for I := 0 to Bitmap.Width - 1 do
    begin
      B := pLine^;
      Inc(pLine);
      G := pLine^;
      Inc(pLine);
      R := pLine^;
      Inc(pLine);
      Canvas.Pixels[I, J] := RGB(R, G, B);
    end;
  end;
end;
Но здесь нужно каждый раз получать указатель на каждую строку битмапа. А если я обращаюсь к ScanLine перед началом считывания (pLine := Bitmap.ScanLine[0]),

Код:
procedure TForm1.DrawBitmap(Canvas: TCanvas);
var
  I, J: Integer;
  pLine: PByte;
  R, G, B: Byte;
begin
  pLine := Bitmap.ScanLine[0];
  for J := 0 to Bitmap.Height - 1 do
  begin
    for I := 0 to Bitmap.Width - 1 do
    begin
      B := pLine^;
      Inc(pLine);
      G := pLine^;
      Inc(pLine);
      R := pLine^;
      Inc(pLine);
      Canvas.Pixels[I, J] := RGB(R, G, B);
    end;
  end;
end;
то в результате получаю ошибку EAccessViolaton.
Miha85193 вне форума Ответить с цитированием
Старый 23.02.2011, 02:34   #2
ArtGrek
DelphiProger
Участник клуба
 
Аватар для ArtGrek
 
Регистрация: 14.11.2010
Сообщений: 1,023
По умолчанию

а что у тебя сохранено в pLine до увеличения на 1, чему оно равно?
Код:
      B := pLine^;
      Inc(pLine);
VirusN13

Последний раз редактировалось ArtGrek; 23.02.2011 в 02:51.
ArtGrek вне форума Ответить с цитированием
Старый 23.02.2011, 02:42   #3
Miha85193
Delphi, OpenGL API
Форумчанин
 
Аватар для Miha85193
 
Регистрация: 29.03.2010
Сообщений: 152
По умолчанию

Цитата:
в коде должен быть указатель?
пиксели и такк можно читать
можно но это будет ужасно медленно, по этому мне и нужно получить прямой доступ к памяти битмапа.
Miha85193 вне форума Ответить с цитированием
Старый 23.02.2011, 02:53   #4
ArtGrek
DelphiProger
Участник клуба
 
Аватар для ArtGrek
 
Регистрация: 14.11.2010
Сообщений: 1,023
По умолчанию

пост выше.
VirusN13
ArtGrek вне форума Ответить с цитированием
Старый 23.02.2011, 07:40   #5
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

GetDIBits(), но по скорости будет не сильно быстрей ScanLine, имхо, ничего плохого в том, что "нужно каждый раз получать указатель на каждую строку битмапа" нет.
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 23.02.2011, 11:10   #6
Miha85193
Delphi, OpenGL API
Форумчанин
 
Аватар для Miha85193
 
Регистрация: 29.03.2010
Сообщений: 152
По умолчанию

Цитата:
GetDIBits(), но по скорости будет не сильно быстрей ScanLine, имхо, ничего плохого в том, что "нужно каждый раз получать указатель на каждую строку битмапа" нет.
А на сколько безопасна функция GetDIBits? Ведь она работает с указателем (Bits: Pointer, если не ошибаюсь).
Miha85193 вне форума Ответить с цитированием
Старый 23.02.2011, 11:43   #7
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

В любом случае она не более опасна, чем ваш метод работы со ScanLine во втором примере )

Код:
pLine: PByte;
Это тоже как бы указатель. Мы ж не в яве или сшарпе. Дельфи + указатели + прямые руки + светлая голова = годный код.
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 23.02.2011, 11:57   #8
Miha85193
Delphi, OpenGL API
Форумчанин
 
Аватар для Miha85193
 
Регистрация: 29.03.2010
Сообщений: 152
По умолчанию

Цитата:
В любом случае она не более опасна, чем ваш метод работы со ScanLine во втором примере )


Код:

pLine: PByte;
Это тоже как бы указатель. Мы ж не в яве или сшарпе. Дельфи + указатели + прямые руки + светлая голова = годный код.
Да, но моя процедура считывает данные через указатель, а GetDIBits записывает, что может вызвать несанкционированный доступ к памяти других, работающих в этот момент процессов и переписать их память, что в свою очередь может вызвать крах системы.

Последний раз редактировалось Miha85193; 23.02.2011 в 12:01.
Miha85193 вне форума Ответить с цитированием
Старый 23.02.2011, 12:11   #9
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

> что может вызвать несанкционированный доступ к памяти других, работающих в этот момент процессов

дануконешно. Процессы изолированы друг от друга уже лет 20, начиная со времен винды 3.11. Без вызова специальных функций прочитать или записать память в другом процессе просто невозможно.

> что в свою очередь может вызвать крах системы

не говоря уже про систему.

Если вы не доверяете своим указателям, довертесь ScanLine, внутри она тоже вызывает GetDIBits().
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 23.02.2011, 12:32   #10
Miha85193
Delphi, OpenGL API
Форумчанин
 
Аватар для Miha85193
 
Регистрация: 29.03.2010
Сообщений: 152
По умолчанию

Цитата:
> что может вызвать несанкционированный доступ к памяти других, работающих в этот момент процессов

дануконешно. Процессы изолированы друг от друга уже лет 20, начиная со времен винды 3.11. Без вызова специальных функций прочитать или записать память в другом процессе просто невозможно.

> что в свою очередь может вызвать крах системы

не говоря уже про систему.

Если вы не доверяете своим указателям, довертесь ScanLine, внутри она тоже вызывает GetDIBits().
Да дело даже не в самом указателе, а в размере выделенной под него памяти. Если к примеру, под указатель выделено один килобайт памяти, а размер памяти данных пикселей битмапа равна двум килобайтам, то здесь я не могу точно сказать, как это отразится на работе моего приложения.
Miha85193 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Получить хендл битмапа tuip Общие вопросы C/C++ 1 27.01.2011 15:45
Создание TBitmap с ScanLine другого битмапа... SalasAndriy Мультимедиа в Delphi 7 25.10.2010 23:47
Недостаточно памяти для большого битмапа Alex Cones Общие вопросы Delphi 15 07.07.2010 07:11
запись битмапа в файл SunKnight Общие вопросы Delphi 8 09.06.2008 08:56
Сжатие битмапа Rapid Мультимедиа в Delphi 7 08.12.2007 16:38