14 / 14 / 5
Регистрация: 13.07.2013
Сообщений: 225
1

Цвет пикселя scanline

13.07.2013, 17:33. Показов 10230. Ответов 23
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, начал изучать делфи,
взял стандартную задачку, найти на картинке нужный пиксель,
по легкому пути через Canvas не пошел,

рекомендуют scanline для скорости, но вот как сравнить цвет пикселя
с нужным мне значением RGB, к примеру (255,0,0) я так и не понял,

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
DC:hdc;
inbmp: TBitmap;
pixel:cardinal;
r,g,b:byte;
x,y:integer;
p: pointer;
 
 
for x := 0 to inbmp.Height-1 do
  begin
    p:= inbmp.ScanLine[x];
    for y := 0 to inbmp.Width-1 do
    begin;
    Pixel:=PCardinal(Integer(p) + y*3)^;
    R:=GetBValue(p[y]);
    G:=GetGValue(p[y]);
    B:=GetRValue(p[y]);
        if RGB(R, G, B) = RGB(255,0,0) then
еще интересует вопрос можно ли как то быстро обрезать картинку кроме как Canvas.CopyRect
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
13.07.2013, 17:33
Ответы с готовыми решениями:

Цвет пикселя!
Ищу в Image все пикселя белового цвета и задаю им другой цвет, но какой бы я цвет не задал (clBlue,...

Цвет пикселя
Ребята, можно ли сохранить цвет пикселя, на которую ты нажал левой кнопкой мыши, в переменную типа...

Получить цвет пикселя с альфаканалом
Здравствуйте. Как получить цвет указанного пикселя с альфаканалом из файла png? Так...

Перемещени курсора на цвет пикселя
мне нужно когда я нажимаю Mouse1(НЕ ТОЛЬКО В ПРОГРАММЕ,а И НА РОБОЧЕМ СТОЛЕ ,к примеру), то курсор...

23
106 / 82 / 15
Регистрация: 07.06.2011
Сообщений: 584
Записей в блоге: 2
13.07.2013, 18:41 2
Цитата Сообщение от pozitiv_rus Посмотреть сообщение
if RGB(R, G, B) = RGB(255,0,0) then[/DELPHI]
на худой конец
Delphi
1
 if (R=255) and (G=0) and (B=0) then
0
Заблокирован
13.07.2013, 19:13 3
Почитай кучу копаний вокруг да около. Половина сходу годится.

http://www.efg2.com/Lab/ImageP... anline.htm

На деле я удивлён что в SIMD наборах ничего нету напрямую для такого(в духе). Разве что париться с переводом во Float или что ещё каждый раз.

Ну или в духе если кратно - поюзать массовое сравнение через PXOR или XORPS. Код простой, но надо с нуля писать.
0
14 / 14 / 5
Регистрация: 13.07.2013
Сообщений: 225
13.07.2013, 19:38  [ТС] 4
Цитата Сообщение от Dr_Quake Посмотреть сообщение
Почитай кучу копаний вокруг да около. Половина сходу годится.

http://www.efg2.com/Lab/ImageP... anline.htm

На деле я удивлён что в SIMD наборах ничего нету напрямую для такого(в духе). Разве что париться с переводом во Float или что ещё каждый раз.

Ну или в духе если кратно - поюзать массовое сравнение через PXOR или XORPS. Код простой, но надо с нуля писать.
я уже нашел эту ссылку, НО где там много примеров? ) там для разных битностей

я пытаюсь считать цвет с bmp 24bit,
там есть пример но я не понял, и даже если сделать как там, то не работает

сделал как в примере, почему не работает (
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
74
unit Unit1;
 
interface
 
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.Button1Click(Sender: TObject);
type
TRGBTriple =  PACKED RECORD
  rgbtBlue : BYTE;
  rgbtGreen: BYTE;
  rgbtRed  : BYTE;
  end;
pRGBTripleArray = ^TRGBTripleArray;
TRGBTripleArray = ARRAY[0..2100000] OF TRGBTriple;
pRGBTriple = ^TRGBTriple;
 
 
var
 
DC:hdc;
inbmp: TBitmap;
pixel:cardinal;
r,g,b:byte;
x,y:integer;
p: pRGBTripleArray;
 
begin
    DC:=GetDC(0);
    inbmp := TBitmap.Create;
    inbmp.PixelFormat:= pf24bit;
    inbmp.Width := screen.Width;
    inbmp.Height := screen.Height;
    bitblt(inbmp.Canvas.Handle, 0, 0, screen.Width, screen.Height, DC, 0, 0, SRCCOPY);
    inbmp.SaveToFile('c:\screen.bmp');
    ReleaseDC(0, DC);
    //inBmp.Free;
 
for x := 0 to inbmp.Height-1 do
  begin
    p:= inbmp.ScanLine[x];
    for y := 0 to inbmp.Width-1 do
    begin;
    if rgbtRed = 255 then
        begin
        showmessage ('123');
        break;
        end;
   end;
  if rgbtRed = 255 then  break;
  end;
 
end;
 
end.
0
Заблокирован
13.07.2013, 19:45 5
ScanLine тебе даёт область памяти, байты там по три, единственный способ искать среди них нужные комбинации - сравнивать их с твоим заданным, ты сравниваешь по байту, это плохо, сравнивать надо как минимум TColor с TColor(ну, с учётом что там 4 байт 0 по дефолту, либо с обычным 3байтовым), ускорить это можно только растя регистр - примеры с MMX не такие сложные, выровнять куда сложнее под это дело хвост.
0
14 / 14 / 5
Регистрация: 13.07.2013
Сообщений: 225
13.07.2013, 20:09  [ТС] 6
я уже разобрался))))

теперь бы еще через scanline картинку обрезать )))
0
14 / 14 / 5
Регистрация: 13.07.2013
Сообщений: 225
19.07.2013, 21:33  [ТС] 7
Кто может подсказать как получить координаты белого пикселя из 1bit картинки?
Delphi
1
2
3
4
5
for x := 0 to bmp.Height-1 do
  begin
    Row := pByteArray(bmp.Scanline[x]);
    for y := 0 to (bmp.Width div 1) - 1 do
  end;
таким методом я могу получать по 8 пикселей, но мне то нужно получить 1 пиксель,
может байт перевести в строку и получить номер единицы?

Может есть способ проще ???
0
Заблокирован
19.07.2013, 22:36 8
Битовые операции, берёшь первый байт/word/dword/qword итд и делаешь

if ((yourbyte AND testbyte)>0) then пиксель белый else пиксель чёрный.
Ну и в зависимости от размерности тестовый байт/word/dword/qword содержит
00000001
00000010
00000100

итд
0
14 / 14 / 5
Регистрация: 13.07.2013
Сообщений: 225
22.07.2013, 21:16  [ТС] 9
Цитата Сообщение от Dr_Quake Посмотреть сообщение
Битовые операции, берёшь первый байт/word/dword/qword итд и делаешь

if ((yourbyte AND testbyte)>0) then пиксель белый else пиксель чёрный.
Ну и в зависимости от размерности тестовый байт/word/dword/qword содержит
00000001
00000010
00000100

итд
Delphi
1
2
3
4
5
A:=$FF  (1111 1111) 255
 
i:=5;  //проверим бит 5
 
if ( (a shr 8-i) and 1 ) = 1  //то 5-ый бит равен 1
1111 1111 shr 3 = 0001 1111

0001 1111 and 1 = 0000 0001 (1) $01

я правильно понял? или есть способ еще быстрее?
первый раз столкнулся с битовыми операциями
0
Заблокирован
22.07.2013, 21:40 10
pozitiv_rus, да тупо же в смысле медленно, зачем так извращаться, сразу AND делается вида.

Pascal
1
2
3
4
5
6
7
8
9
10
case i of
1: if ((a AND 1)=0) then result:=0 else result:=1;
2: if ((a AND 2)=0) then result:=0 else result:=1;
3: if ((a AND 4)=0) then result:=0 else result:=1;
4: if ((a AND 8)=0) then result:=0 else result:=1;
5: if ((a AND 16)=0) then result:=0 else result:=1;
6: if ((a AND 32)=0) then result:=0 else result:=1;
7: if ((a AND 64)=0) then result:=0 else result:=1;
8: if ((a AND 128)=0) then result:=0 else result:=1;
end;
Добавлено через 1 минуту
В асме это выглядит покороче к слову, и 3 операции в любом случае всего.
Аналогично почему используются таблицы для значений функций много где - для скорости.
1
14 / 14 / 5
Регистрация: 13.07.2013
Сообщений: 225
22.07.2013, 21:45  [ТС] 11
Цитата Сообщение от Dr_Quake Посмотреть сообщение
pozitiv_rus, да тупо же в смысле медленно, зачем так извращаться, сразу AND делается вида.

Pascal
1
2
3
4
5
6
7
8
9
10
case i of
1: if ((a AND 1)=0) then result:=0 else result:=1;
2: if ((a AND 2)=0) then result:=0 else result:=1;
3: if ((a AND 4)=0) then result:=0 else result:=1;
4: if ((a AND 8)=0) then result:=0 else result:=1;
5: if ((a AND 16)=0) then result:=0 else result:=1;
6: if ((a AND 32)=0) then result:=0 else result:=1;
7: if ((a AND 64)=0) then result:=0 else result:=1;
8: if ((a AND 128)=0) then result:=0 else result:=1;
end;
Добавлено через 1 минуту
В асме это выглядит покороче к слову, и 3 операции в любом случае всего.
Аналогично почему используются таблицы для значений функций много где - для скорости.
спасибо, так действительно короче, у меня была идея использовать case, но меня сбила процедура с другого сайта, которая еще и с ошибкой была

Delphi
1
2
3
4
5
6
function IsBitSet(Value: cardinal; BitNum : byte): boolean;
begin
  result:=((Value shr BitNum) and 1) = 1
end;
...
if IsBitSet(43691,1) then //установлен (равен 1)
буду разбираться дальше
0
Заблокирован
22.07.2013, 21:47 12
Это не короче - короче как раз с shr/l в коде на Delphi, но это быстрее, а это очень критично в таких операциях.
0
14 / 14 / 5
Регистрация: 13.07.2013
Сообщений: 225
22.07.2013, 21:49  [ТС] 13
Цитата Сообщение от Dr_Quake Посмотреть сообщение
Это не короче - короче как раз с shr/l в коде на Delphi, но это быстрее, а это очень критично в таких операциях.
я обрабатываю, BMP, поэтому главное скорость кода, пробовал через bmp24 bit, как в начале темы,
теперь вот хочу через 1bit сделать, и посмотреть что быстрее
0
Заблокирован
22.07.2013, 21:50 14
Тогда так вообще не делают. Обрабатывать надо не конвертируя биты в байты, а прямо на месте. Далее всё уже зависит от того, что и как делаешь.
0
14 / 14 / 5
Регистрация: 13.07.2013
Сообщений: 225
22.07.2013, 21:55  [ТС] 15
так ведь scanline в случае pf1bit возвращает строку байтов?
каждый байт по 8 пикселей содержит

или я не правильно понял
0
Заблокирован
22.07.2013, 21:58 16
Да, но работать то как-то с ними надо, потому никакого result и процедур вроде GetPixel
0
14 / 14 / 5
Регистрация: 13.07.2013
Сообщений: 225
22.07.2013, 22:02  [ТС] 17
Цитата Сообщение от Dr_Quake Посмотреть сообщение
Да, но работать то как-то с ними надо, потому никакого result и процедур вроде GetPixel
так я вроде так и не делаю

Delphi
1
2
3
4
5
6
7
8
9
10
11
 
for x := 0 to bmp.Height-1 do //строки BMP
  begin
    Row := pByteArray(bmp.Scanline[x]); // Строка байтов из строки X BMP
    for y := 0 to (bmp.Width div 8) - 1 do
       begin
       вот тут уже делаем через кейс и смотрим какой бит равен 1
       end;
  end;
 
ну и получаем координаты пикселя к примеру (x, (y-1)*8 + номер нашего бита)
так?

по логике должно работать )
0
Заблокирован
23.07.2013, 10:09 18
Работать то должно, но те же операции сравнения и присваивания надо делать сразу формируя свой байт и сравнивая по 8, а не вытаскивая биты.
0
14 / 14 / 5
Регистрация: 13.07.2013
Сообщений: 225
30.07.2013, 21:24  [ТС] 19
Цитата Сообщение от Dr_Quake Посмотреть сообщение
Работать то должно, но те же операции сравнения и присваивания надо делать сразу формируя свой байт и сравнивая по 8, а не вытаскивая биты.
не совсем понял, что ты имеешь в виду
0
Заблокирован
30.07.2013, 21:34 20
Ровно что написал. Работать блоками даже больше чем минимальный байт везде где возможно. Это вообще ко всем операциям вычислений относится.
0
30.07.2013, 21:34
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
30.07.2013, 21:34
Помогаю со студенческими работами здесь

Цвет пикселя под курсором
procedure TForm1.tMR1Timer(Sender: TObject); var p: TPoint; DC: HDC; begin ...

Как определить цвет пикселя по курсором?
Подскажите, задача такая: Я перемещаю курсор в определенные координаты, мне нужно определить цвет...

Можно ли получить цвет пикселя картинки, не выводя ее?
Здравствуйте. Подскажите, можно ли получить цвет определенного пикселя картинки, не выводя ее на...

Как определить цвет пикселя на jpg картинке?
может кто знает как определить цвет пикселя...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru