Форум программистов, компьютерный форум, киберфорум
Delphi: Графика, звук, видео
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.58/55: Рейтинг темы: голосов - 55, средняя оценка - 4.58
68 / 33 / 11
Регистрация: 18.07.2014
Сообщений: 263

Побитовые операции с памятью

16.03.2020, 18:01. Показов 12643. Ответов 150
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть ли в Delphi какие-нибудь функции чтобы побитово сделать and or xor not с двумя произвольными кусками памяти? Можно чтобы это были обязательно два равных по длине куска, неважно.
Например для сравнения двух кусков есть очень быстрая функция CompareMem.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
16.03.2020, 18:01
Ответы с готовыми решениями:

Побитовые операции
Задание: Дано целое неотрицательное число. Определить количество составляющих его шестнадцатеричных цифр, содержащих в двоичном...

Побитовые операции
С помощью побитовых операций преобразовать число -78 в 15 Вот что пыталась делать, кто знает как сделать? int v =-78; int i = 1; ...

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

150
68 / 33 / 11
Регистрация: 18.07.2014
Сообщений: 263
29.03.2020, 18:20  [ТС]
Студворк — интернет-сервис помощи студентам
murderer, Да, последняя. Альфу заполнять у сэмпла всё таки надо. Вот, обрати внимание в ro32.bmp на зелёную полоску. Я опытным путём выяснил что если её закрасить, то находит. Почему именно так я не понял. Если бы весь левый столбец надо было красить альфой, то было бы примерно понятно почему, а так непонятно.
0
68 / 33 / 11
Регистрация: 18.07.2014
Сообщений: 263
29.03.2020, 18:22  [ТС]
Там ещё есть копия куска который я вырезал без прозрачности.

Просто я этот код поиска не только не понимаю, но ещё и отладить не могу(
Вложения
Тип файла: rar Shader2.rar (3.62 Мб, 8 просмотров)
0
4195 / 1841 / 223
Регистрация: 06.10.2010
Сообщений: 4,127
29.03.2020, 20:10
Есть подозрение, что при выборке из текстуры выбирается не тот пиксель, который нужен. Дело в том, что шейдеру для выборки нужно указывать координаты в диапазоне от 0 до 1 и я перевожу пиксельные координаты в этот диапазон при помощи деления:
Code
1
vec4 s=texture(T1,counter/tex1Size);
Точность вычислений в шейдере 32 бита, может быть её не хватает.

Ну и ещё как вариант выбирается не точное значение пикселя, а интерполированное с учётом соседей (хотя я указал GL_NEAREST, то есть не использовать интерполяцию).

В общем нужно разбираться. Как отлаживать шейдеры я тоже толком не знаю.

Добавлено через 2 минуты
Да если взять сэмпл с котом (на котором всё работает правильно) и обрезать его, то может перестать работать, а может и нет - зависит от получившихся размеров.
0
240 / 218 / 46
Регистрация: 17.04.2010
Сообщений: 526
29.03.2020, 23:27
Набросал свой вариант поиска с прозрачностью.

test.zip
1
68 / 33 / 11
Регистрация: 18.07.2014
Сообщений: 263
30.03.2020, 08:27  [ТС]
x128, Спросони долго вкуривал твой алгоритм. Я так понял, ты сэмпл преобразовываешь в длинный такой массив из непрозрачных пикселей (вместе с координатами). Там надо допилить напильником немного чтобы установить альфу. Но если честно, я не понял почему оно быстро работает. Если непрозрачную картинку подсунуть, то сложность получается примерно такая не как и при сравнении по три байта.
0
240 / 218 / 46
Регистрация: 17.04.2010
Сообщений: 526
30.03.2020, 09:12
Цитата Сообщение от KOTOM Посмотреть сообщение
Я так понял, ты сэмпл преобразовываешь в длинный такой массив из непрозрачных пикселей (вместе с координатами).
Всё верно, у меня было несколько идей как поступить с прозрачностью, остановился на таком варианте.
Цитата Сообщение от KOTOM Посмотреть сообщение
Там надо допилить напильником немного чтобы установить альфу.
Сравнение выполняется по четыре байта, соответственно для холста нужно в альфу положить FF, ну и для семпла без прозрачности также.
Цитата Сообщение от KOTOM Посмотреть сообщение
Но если честно, я не понял почему оно быстро работает.
Магия На самом деле там могут прилететь тормоза, специфичное содержания холста и/или семпла может заставить выполнять кучу ненужных сравнений, это будет худший случай. Для лучшего случая сравнений будет не больше количества пикселей в подложке. Худший расклад хоть и маловероятен, но не исключен.
0
68 / 33 / 11
Регистрация: 18.07.2014
Сообщений: 263
30.03.2020, 09:55  [ТС]
x128, Просто я примерно такой же алгоритм делал, и он по сравнению с твоим отрабатывал намного дольше даже для непрозрачных картинок. Сейчас покажу.

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function FindInRegionMemCmp(var Src:TBitmap; x,y,dx,dy:Integer; var Sample:TBitmap):TPoint;
var i,j,i2,j2:Integer; Dif:Boolean;
begin
Result:=Point(-1,-1);
if (Sample=nil) or (x>=dx) or (y>=dy) or (x<0) or (y<0) then Exit;
if (Sample.Width>(dx-x)) or (Sample.Height>(dy-y)) then Exit;
if Src=nil then Exit;
 
Src.PixelFormat:=pf24bit;
Sample.PixelFormat:=pf24bit;
 
for i:=x to dx-Sample.Width do for j:=y to dy-Sample.Height do begin
 
for j2:=j to j+Sample.Height-1 do begin
Dif:=not CompareMem(Pointer(DWORD(Src.ScanLine[j2])+i*3),Pointer(Sample.ScanLine[j2-j]),Sample.Width*3);
if Dif then Break; end;
 
if not Dif then begin Result.X:=i; Result.Y:=j; Exit; end;
end;
end;
Он сравнивает сразу весь кусок памяти через сканлайны, размером с ширину сэмпла. Сам CompareMem сравнивает до первого разричия, как я понял, побайтово. работает примерно 1 секунду на моём примере. Твой алгоритм 6 милисекунд на моём (без прозрачности). Вот я не понимаю, в чём я ошибся.
0
240 / 218 / 46
Регистрация: 17.04.2010
Сообщений: 526
30.03.2020, 12:20
Цитата Сообщение от KOTOM Посмотреть сообщение
Вот я не понимаю, в чём я ошибся.
Как минимум в получении ScanLine во вложенном цикле. Это неправильно. В худшем случае это нужно делать для строки, а еще лучше позаботиться заранее и в цикле работать только с данными. Еще ты сравниваешь строку целиком, а я проверяю один пиксель и этого достаточно чтобы понять есть смысл проверять дальше или переходить ко следующей позиции. Как-то так.
0
68 / 33 / 11
Регистрация: 18.07.2014
Сообщений: 263
30.03.2020, 13:14  [ТС]
x128, Ну строка целиком внутри CompareMem сравнивается вообще побайтово насколько я понял. Просто эта функция работает намного быстрее чем вот эта

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function FindInRegion(var Src:TBitmap; x,y,dx,dy:Integer; var Sample:TBitmap; HasTransparentColor:Boolean=False; TransparentColor:TColor=clFuchsia):TPoint;
var i,j,i2,j2:Integer; Dif:Boolean; tc:Pointer;
begin
Result:=Point(-1,-1);
if (Sample=nil) or (x>=dx) or (y>=dy) or (x<0) or (y<0) then Exit;
if (Sample.Width>(dx-x)) or (Sample.Height>(dy-y)) then Exit;
if Src=nil then Exit;
 
GetMem(tc,3);
PByte(DWORD(tc)+2)^:=Byte(TransparentColor);
PByte(DWORD(tc)+1)^:=Byte(TransparentColor shr 8);
PByte(DWORD(tc))^:=Byte(TransparentColor shr 16);
 
for i:=x to dx-Sample.Width do for j:=y to dy-Sample.Height do begin
Dif:=False;
for i2:=0 to Sample.Width-1 do begin for j2:=0 to Sample.Height-1 do begin
Dif:=not CompareMem(Pointer(DWORD(Src.ScanLine[j+j2])+(i+i2)*3),Pointer(DWORD(Sample.Scanline[j2])+i2*3),3) or (HasTransparentColor and (CompareMem(tc,Pointer(DWORD(Sample.Scanline[j2])+i2*3),3)));
if Dif then Break; end;
if Dif then Break; end;
if not Dif then begin Result.X:=i; Result.Y:=j; FreeMem(tc); Exit; end;
end;
FreeMem(tc);
end;
А тут как раз сравнивается попиксельно. Именно поэтому я и в недоумении. Неужели взятие сканлайна настолько тормозит? Немного погодя перепишу эту функцию, пусть берёт сканлайн как у тебя, и доложу о результатах.
0
240 / 218 / 46
Регистрация: 17.04.2010
Сообщений: 526
30.03.2020, 14:21
Цитата Сообщение от KOTOM Посмотреть сообщение
Неужели взятие сканлайна настолько тормозит?
Всё можно посмотреть в исходниках:
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
68 / 33 / 11
Регистрация: 18.07.2014
Сообщений: 263
30.03.2020, 16:09  [ТС]
x128, Я кстати это видел, но прикинул что это не будет особо накладно) Ну, проверю - расскажу.

Добавлено через 1 час 41 минуту
В общем на самом деле взятие сканлайна оказалось очень длительным процессом. Мне было лень сегодня думать, поэтому я просто взял и все сканлайны буферизировал в массив, и получилось намного быстрее.

Так же я выяснил, что сравнивать по 4 байта через = быстрее чем три байта через CompareMem.

Надеюсь на днях хватит сил всё это привести в нормальный вид, а то пока эта функция выглядит как танковый полигон.

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
function FindInRegion(var Src:TBitmap; x,y,dx,dy:Integer; var Sample:TBitmap; HasTransparentColor:Boolean=False; TransparentColor:TColor=clFuchsia):TPoint;
var i,j,i2,j2:Integer; Dif:Boolean; tc:PDWORD; SSRc,SSample:array of Pointer;
begin
Result:=Point(-1,-1);
if (Sample=nil) or (x>=dx) or (y>=dy) or (x<0) or (y<0) then Exit;
if (Sample.Width>(dx-x)) or (Sample.Height>(dy-y)) then Exit;
if Src=nil then Exit;
 
Src.PixelFormat:=pf32Bit; Sample.PixelFormat:=pf32Bit;
 
SetLength(SSrc,Src.Height-1);
for i:=0 to Src.Height-1 do SSrc[i]:=Src.ScanLine[i];
SetLength(SSample,Sample.Height-1);
for i:=0 to Sample.Height-1 do SSample[i]:=Sample.ScanLine[i];
 
GetMem(tc,4);
PByte(tc)^:=Byte(TransparentColor shr 16);
PByte(DWORD(tc)+1)^:=Byte(TransparentColor shr 8);
PByte(DWORD(tc)+2)^:=Byte(TransparentColor);
PByte(DWORD(tc)+3)^:=$00;
 
for i:=x to dx-Sample.Width-1 do for j:=y to dy-Sample.Height-1 do begin
Dif:=False;
for i2:=0 to Sample.Width-1 do begin for j2:=0 to Sample.Height-1 do begin
Dif:=not((PDWORD(DWORD(SSrc[j+j2])+(i+i2)*4)^=PDWORD(Pointer(DWORD(SSample[j2])+i2*4))^) or (HasTransparentColor and ((tc^=PDWORD(DWORD(SSample[j2])+i2*4)^))));
if Dif then Break; end;
if Dif then Break; end;
if not Dif then begin Result.X:=i; Result.Y:=j; SetLength(SSrc,0); SetLength(SSample,0); FreeMem(tc); Exit; end;
end;
SetLength(SSrc,0); SetLength(SSample,0); FreeMem(tc);
end;
Попутно кстати два бага нашёл)
0
 Аватар для GoodWeather
886 / 588 / 179
Регистрация: 28.02.2017
Сообщений: 2,359
Записей в блоге: 1
30.03.2020, 20:42
ого... Ну вы тут и нашаманили, пока у меня не было времени поразбираться с вопросом... %))))
Чё-то уже окончательно потерял нить происходящего.

Добавлено через 7 минут
Нужно избегать лишних конвертаций, лишних копирований, лишних массивов, лишних вызовов функций, попробовать раскрутку цикла на 4 или 8.
Delphi
1
2
Src.PixelFormat:=pf32Bit;
Sample.PixelFormat:=pf32Bit;
Вы понимаете, что если битмапы были не 32-битные, то произойдёт:
  • создание нового битмапа другого формата;
  • копирование пикселей, а учитывая что форматы разные - это будет долго;
  • удаление старого битмапа;
Delphi
1
for i:=0 to Src.Height-1 do SSrc[i]:=Src.ScanLine[i];
ScanLine[] - жутко дорогая операция. Вам же показали выше её устройство.
Вы понимаете что именно делают Changing(), DIBNeeded() и GDIFlush()? А ведь они вообще по сути не нужны.
Delphi
1
SSRc,SSample:array of Pointer;
Зачем? Выделение памяти занимает время. Заполнение занимает время.
Delphi
1
PByte(DWORD(tc)+1)^:=Byte(TransparentColor shr 8);
Что за каша такая? Надо описать нормальные типы данных.

Добавлено через 2 минуты
Кажется тут пришли профи по SSE/AVX. И кажется даже чем-то покруче.
Почему вы всё ещё делаете вот так как в #111?

Добавлено через 9 минут
От DIB-секции требуется только:
  • PixelFormat - Формат данных;
  • Scan0 - Указатель на начало данных;
  • Height - Количество строк;
  • Width - Количество пикселей в строке;
  • Stride - Длина строки в байтах;
Это всё получается заранее и как можно реже.
И уж точно не в циклах.
0
4195 / 1841 / 223
Регистрация: 06.10.2010
Сообщений: 4,127
30.03.2020, 20:45
я просто взял и все сканлайны буферизировал в массив
Зачем тебе куча указателей на строки, если можно использовать 1 указатель на начало растра? Я же показывал как обращаться к растру через динамический массив.

В общем с шейдерами я наигрался. Вроде бы поиск заработал, но при первом запуске отрабатывает очень долго: около 300 мс, повторные запуски проходят за 10-12 мс, причём большую часть времени занимает вызов glGetNamedBufferSubData. В любом случае код от x128 работает быстрее и наверное его можно немного ускорить если:
1) Делать выход из цикла через goto
2) В массив smp записывать не x и y, а линейный индекс внутри скриншота (y*width+x) и обращаться к растру не через сканлайны, а по нормальному через динамический массив.
3) В цикле repeat заменить "Image1.Width-Image2.Width" на заранее вычисленную переменную.

Кстати там интересное объявление массива:
Code
1
array[word] of pRGBLine
не знал, что так можно.
Вложения
Тип файла: 7z Shader.7z (7.04 Мб, 16 просмотров)
0
4195 / 1841 / 223
Регистрация: 06.10.2010
Сообщений: 4,127
31.03.2020, 08:32
Немного оптимизировал код от x128, Как вам такое:

И это без ассемблера. А ведь этот алгоритм ложится на AVX2/AVX-512 (инструкция VGATHERDPS).
1
4195 / 1841 / 223
Регистрация: 06.10.2010
Сообщений: 4,127
31.03.2020, 08:33
И время посчитано с учётом заполнения массива smp.
0
68 / 33 / 11
Регистрация: 18.07.2014
Сообщений: 263
31.03.2020, 13:02  [ТС]
murderer, Я просто вчера спать хотел, но захотелось быстро протестировать насколько медленный Scanline[i], вот как раз сейчас мотивируюсь переписать по нормальному. Хочу как раз попробоваить через один указатель расчитывать, ну как ты говорил через ScanLine[Height-1] и там дальше арифметикой. Придётся сравнивать снизу вверх насколько я понял, но это неважно. А ещё хочу переписать код от x128, в более юзательный вид. Там очень интересный алгоритм который я не до конца понимаю. И кстати да, array[word] тоже впервые увидел) Я до этого юзал только array[0..0] of что-тотам.

Добавлено через 35 минут
GoodWeather,
Delphi
1
2
Src.PixelFormat:=pf32Bit;
Sample.PixelFormat:=pf32Bit;
Как будто это сделать быстрее, чем сравнивать по три байта.
0
 Аватар для snake32
3591 / 1721 / 236
Регистрация: 26.02.2009
Сообщений: 8,724
Записей в блоге: 5
31.03.2020, 14:56
Цитата Сообщение от murderer Посмотреть сообщение
Немного оптимизировал код от x128
А где код?
Цитата Сообщение от KOTOM Посмотреть сообщение
Как будто это сделать быстрее, чем сравнивать по три байта.
32 бита позволяет избавиться от выравнивания строк в памяти у BMP (4 байта).
То есть в BMP любая строка занимает объём кратно 4 байтам, а так как один пиксель при 32-битах и есть 4 байта, то
все строки лежат плотно независимо от разрешения картинки по ширине.

Ну и выделять память (GetMem) на каждый пиксель, та ещё оптимизация... а если ещё захотите распараллелить на несколько потоков то потоки будут блокировать друг друга на вызове GetMem, так как выделение памяти не параллелится
0
68 / 33 / 11
Регистрация: 18.07.2014
Сообщений: 263
31.03.2020, 16:43  [ТС]
snake32, Насчёт трёх байт я имел ввиду, что в 24 битном битмапе один пиксель занимает три байта. Поэтому чем сравнивать трёхбайтные пиксели (а это только через CompareMem делать, а он работает побайтово), быстрее будет конвертнуть в 32 бита и сравнивать просто через <> по 4 байта сразу.

Добавлено через 52 секунды
Я впринципе уже переписал этот страх и ужас, сейчас сижу придумываю как быть с x,dx,y,dy пока только по всему изображению работает.

Добавлено через 1 час 26 минут
В общем вот так у меня получилось. Всё что мог оптимизировал и буферизировал. Выглядит конечно так себе.

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
function FindInRegion(var Src:TBitmap; x,y,dx,dy:Integer; var Sample:TBitmap; HasTransparentColor:Boolean=False; TransparentColor:TColor=clFuchsia):TPoint;
var
  i,j,i2,j2,SrcWx4,SamWx4,SHm1,SWm1,buf1,buf2,buf3:Integer;
  Dif:Boolean; TransparentColorBGRA:DWORD; PSrc,PSample:Pointer;
begin
Result:=Point(-1,-1);
if (Sample=nil) or (x>=dx) or (y>=dy) or (x<0) or (y<0) then Exit;
if (Sample.Width>(dx-x)) or (Sample.Height>(dy-y)) then Exit;
if Src=nil then Exit;
 
Src.PixelFormat:=pf32Bit; Sample.PixelFormat:=pf32Bit;
SrcWx4:=Src.Width*4;
SamWx4:=Sample.Width*4;
SHm1:=Sample.Height-1;
SWm1:=Sample.Width-1;
 
PSrc:=Src.ScanLine[Src.Height-1];
PSample:=Sample.ScanLine[Sample.Height-1];
 
TransparentColorBGRA:=TransparentColor;
asm
mov eax,TransparentColorBGRA
and eax,$00FFFFFF
bswap eax
ror eax,8
mov TransparentColorBGRA,eax
end;
 
for j:=Src.Height-Sample.Height-y downto Src.Height-dy do begin
buf1:=DWORD(PSrc)+j*SrcWx4;
for i:=x to dx-Sample.Width do begin
Dif:=False;
for j2:=0 to SHm1 do begin
buf3:=DWORD(PSample)+j2*SamWx4;
buf2:=j2*SrcWx4;
for i2:=0 to SWm1 do begin
Dif:=(PDWORD(buf1+buf2+(i+i2)*4)^<>PDWORD(buf3+i2*4)^) and not (HasTransparentColor and (TransparentColorBGRA=PDWORD(buf3+i2*4)^));
if Dif then Break; end;
if Dif then Break; end;
if not Dif then begin Result.X:=i; Result.Y:=Src.Height-j-j2; Exit; end;
end; end;
end;
Добавлено через 3 минуты
Но у меня по жизни небольшие проблемы с координатами. Я проверил вроде всё, в том числе углы. Вроде работает, нигде не вылетает в не ту память.
0
 Аватар для GoodWeather
886 / 588 / 179
Регистрация: 28.02.2017
Сообщений: 2,359
Записей в блоге: 1
31.03.2020, 16:56
Что значит по 3 байта? У 24-хбитных битмапов блоки идут строго друг за другом, без пропусков.
Если оба битмапа 24-хбитные - сравнивать можно так же хоть по 4 хоть по 8, хоть по 16 байт, проблема только что придётся "хвост" отдельно контролировать.
А вот каждый раз проверять и упаси вдруг если ещё и конвертировать PixelFormat - это очень накладно. Вы проверяли сколько это длится? Оно же весь массив копирует со сдвигами/перестановками байт.
Об формате надо заботиться заранее. Менять Width/Height/PixelFormat надо как можно реже. Битмапы вы сами создаёте, или они откуда-то приходят?

Не по теме:

Кстати, выравнивание обязательно только в BMP-файле на диске. В памяти это уже опционально. Но при загрузке из файла выравнивание проще оставить как есть, возможно только поэтому оно почти всегда присутствует.



Добавлено через 3 минуты
Зачем вам вообще PSrc,PSample:Pointer;?
Зачем вы выделяете под них память и заполняете через очень тормознутый ScanLine[] при каждом вызове FindInRegion()?
Даже если использовать массивы указателей (кстати, по-науке то что вы сделали называется row_ptr_cache) то это надо делать только один раз после изменений свойств Width/Height/PixelFormat, а не постоянно.

Добавлено через 6 минут
Узнать указатель Scan0 можно через WinAPI или через TBitmap.ScanLine[0].
Узнать Strde можно одновременно через тот же WinAPI или вычитанием Scan0 и TBitmap.ScanLine[1].
Вот со знаком Strde может быть проблемка, WinAPI его что-то не даёт, возможно методом TBitmap безопаснее.

Добавлено через 2 минуты
Цитата Сообщение от KOTOM Посмотреть сообщение
Delphi
1
FindInRegion(var Src: TBitmap; ...
TBitmap это уже указатель, зачем вы указатель передаёте как Var?
0
68 / 33 / 11
Регистрация: 18.07.2014
Сообщений: 263
31.03.2020, 17:08  [ТС]
GoodWeather, Src приходить будет со скриншота текущего экрана. Sample грузиться с диска (Его можно сразу сделать 32битным, тогда конвертироваться не будет, просто сравнит что он уже 32 битный). Чтобы сравнить попиксельно (у 24 битных битмапов пиксель 3 байта) нудно использовать CompareMem, а он сравнивает по 1 байту в цикле. А вот у 32 битного битмапа пиксель 4 байта, и можно сравнивать просто два DWORD.

Под PSrc и PSample память не выделяется. Это указатели на последний сканлайн битмапа. Ещё лучше их не получить. Вообще как бы подразумевается что FindInRegion не будет вызываться слишком часто.

Добавлено через 1 минуту
var по привычке использую. Битмап внутри может меняться.

Добавлено через 20 секунд
var по привычке использую. Битмап внутри может меняться.

Добавлено через 1 минуту
Так как битмап хранится снизу вверх я использую TBitmap.ScanLine[TBitmap.Height-1],а не TBitmap.ScanLine[0].

Добавлено через 7 минут
murderer, Скинь пожалуйста свой модифицированный код. Я ту функцию чисто из-за спортивного интереса добивал) Твоя быстрее будет.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
31.03.2020, 17:08

Побитовые операции
Выбрать алгоритм, составить его блок-схему и программу для решения выбранного варианта задания. Во всех вариантах предполагается, что...

Побитовые операции
Всем доброго утра. Дана такая задача: есть два чсила,поменять местами 2 последние цифры этих чисел между собой, т.е. 2 последних Х заменить...

Побитовые операции
От друга услышал идею о побитовой сортировки имен (например). К примеру, если у нас набор структурных переменных с анкетами работников, и...

Побитовые операции
Задача: битовый образ 8*8 задается при помощи 8 байт, каждый байт состоит, соответственно, из 8 бит, бит={0,1}; при помощи побитовых...

Побитовые операции
Помогите решить несколько задач по битовым операциям,они все малы по реализации. И объяснить начиная с 3 задачи,что нужно сделать?А то не...


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

Или воспользуйтесь поиском по форуму:
120
Ответ Создать тему
Новые блоги и статьи
Был там один разговор по поводу свободы в материальном мире.
kumehtar 19.08.2026
Суть: рассматривается живое существо, оказавшееся внутри довольно странной системы (этого мира) и пытающееся обустроить в ней свой кусок пространства. Жизнь действительно предъявляет каждому. . .
Когда логика программы не спасает от человеческих ошибок
Maks 18.08.2026
В последнее время всё чаще и чаще сталкиваюсь с таким явлением, как абсолютная невнимательность (или глупость) пользователей. Проявляется это чаще всего на работе в коллективе. Допустим, человек с. . .
Лето уходит
kumehtar 17.08.2026
Мысли в слух
kumehtar 17.08.2026
Забавно, насколько сейчас стала доступна информация. Например о магии, духовном развитии, медитациях, и других подобных направлениях, ранее зачастую тайных, передаваемых от учителя к ученику. Хотя. . .
Перемещение строк из ТЧ в другой документ с учетом текущего пробега
Maks 17.08.2026
Реализация из решения ниже выполнена на примере нетипового документа "Автозапчасти", с ТЧ "Шины". За основу взят алгоритм отсюда: https:/ / www. cyberforum. ru/ blogs/ 359708/ 10838. html Задача: . . .
Саморегулирующийся социальный контракт для сервера cross-section.
Hrethgir 14.08.2026
С кодом конечно таких глубоких размышлений пока не было, впрочем я уже привык к алгоритмизации. Суть предмета записи: снова в диалоге с нейросетью (я взял пока себе ник для учётки админа - Rector). . . .
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru