// картинка предварительно сохранена в фотошопе в формате bmp 5-6-5
// pix - цвет пикселя
// s - строка (string) с цветом в формате hex
...
pix:= Image1.Canvas.Pixels[k,Image1.Picture.Height-1-i];
r1:=GetRValue(pix) shr 3;
g1:=GetGValue(pix) shr 2;
b1:=GetBValue(pix) shr 3;
pix:= (r1 shl 11) + (g1 shl 5) + b1; // получили цвет
// можем перевести его в hex формат
s:=IntToHex(pix,4);
Как передать 16-тиричное число через com порт? Изображение. USB дисплей.
1. Чтобы получить цвет каждого пиксела, мы с каждым пикселем картинки проделываем следующее:
Код:
Т.е. для каждой из 5 точек знаем её цвет: F800, 0000, 0000, FFFF, FFFF
2. Дисплей работает в -5-6-5- (-R-G-B-) режиме цветопередачи. Это означает, что в потоке данных первые 5 бит устанавливают красный цвет, следующие 6 - зеленый, и последние 5 синий. (0xFFFF белый, 0x0000 черный).
3. Необходимо передать цвета каждого пикселя картинки контроллеру ATMega8, а он отправит их в дисплей.
4. В Delphi использую компонент CPortLib.
Для записи в порт у него есть:
Write - Writes non-typed variable to output buffer.
WriteAsync - Writes non-typed variable to output buffer in asynchronous mode.
WriteStr - Writes string type variable to output buffer.
WriteStrAsync - Writes string type variable to output buffer in asnychronous mode.
5. Как их передать? Т.е. как передать 16-тиричное число через com порт?
В чем проблема? Кодируй его в слово (Word) по схеме 5-6-5 бит и отправляй.
Код:
function WriteStr (const Str: string):integer;
function Write (const mbuffer: PAnsiChar; Count: integer):integer;
function Write (const mbuffer: PAnsiChar; Count: integer):integer;
Цитата:
... 2 байта также называют словом (word). Отсюда и название соответствующего числового типа данных - Word (число, занимающее в памяти 2 байта, значения от 0 до 65535)
Код:
ComPort1.WriteStr(IntToStr(pix));
И всё что ли? Но это строка.
Код:
PixColorArray: array of Word;
...
PixColorArray[0]:=pix; // для одной точки (пока)
ComPort1.Write(PixColorArray[0],2);
...
PixColorArray[0]:=pix; // для одной точки (пока)
ComPort1.Write(PixColorArray[0],2);
[Error]: Incompatible types: 'Word' and 'PAnsiChar'
Код:
ComPort1.Write(Addr(PixColorArray[0]),2);
Компилируется, но при нажатии на кнопку ошибка в этой строке PixColorArray[0]:=pix;
Пример из справки к компоненту:
Код:
var
Str: String;
begin
Str := 'Hello';
ComPort1.WriteStr(Str); // string type variable
ComPort1.Write(Str[1], Length(Str)); // no defined type
end;
Str: String;
begin
Str := 'Hello';
ComPort1.WriteStr(Str); // string type variable
ComPort1.Write(Str[1], Length(Str)); // no defined type
end;
Код:
var Color: Word; // Здесь наш цвет
ColorStr: string;
begin
ColorStr := Chr(Color and $00FF);
ColorStr := ColorStr + Chr((Color and $FF00) shr 8);
ComPort1.Write(PAnsiChar(ColorStr), 2);
end;
ColorStr: string;
begin
ColorStr := Chr(Color and $00FF);
ColorStr := ColorStr + Chr((Color and $FF00) shr 8);
ComPort1.Write(PAnsiChar(ColorStr), 2);
end;
Вообще, не понятно, как должны быть отосланы цвета, каков порядок байт и т.п. Кроме того, у твоего компонента все таки должен быть метод, позволяющий посылать raw буфер (просто массив байт), а то получаются какие-то пляски с бубном, ей богу...
http://sourceforge.net/projects/comport/files/ там в нем есть справка. Посмотрите пожалуйста. Может я чего не углядел.
А какой компонент для com порта лучше взять? Может ещё чего есть?
Вот сам компонент:
А какой компонент для com порта лучше взять? Может ещё чего есть?
У него функция:
Код:
function Write(const Buffer; Count: Integer): Integer;
Код:
procedure TForm1.Button2Click(Sender: TObject);
var i: integer;
r1,g1,b1:integer;
begin
i:=clred;
r1:=GetRValue(i) shr 3;
g1:=GetGValue(i) shr 2;
b1:=GetBValue(i) shr 3;
i:= (r1 shl 11) + (g1 shl 5) + b1;
form1.Caption :=' Старший байт='+IntToHex(Hi(i),2)+'Младший байт='+IntToHex(Lo(i),2);
end;
var i: integer;
r1,g1,b1:integer;
begin
i:=clred;
r1:=GetRValue(i) shr 3;
g1:=GetGValue(i) shr 2;
b1:=GetBValue(i) shr 3;
i:= (r1 shl 11) + (g1 shl 5) + b1;
form1.Caption :=' Старший байт='+IntToHex(Hi(i),2)+'Младший байт='+IntToHex(Lo(i),2);
end;
Как эти 2 байта отправить в ком порт???????
Код:
BComPort1.Open;
BComPort1.Write(Hi(i),sizeof(Hi(i))); //ругается [Error] Unit1.pas(71): Variable required
BComPort1.Write(Hi(i),sizeof(Hi(i))); //ругается [Error] Unit1.pas(71): Variable required
Существенный прогресс!!!!!!!! Работает!!!!!!!! Я поставил компонент TBComPort
Код:
procedure TForm1.Button2Click(Sender: TObject);
var r1,g1,b1:integer;
Data: Byte;
begin
r1:=GetRValue(i) shr 3;
g1:=GetGValue(i) shr 2;
b1:=GetBValue(i) shr 3;
i:= (r1 shl 11) + (g1 shl 5) + b1; // i - глобальная integer, из ColorDialog1
BComPort1.Open;
Data := Hi(i);
BComPort1.Write(Data, SizeOf(Data));
Data := Lo(i);
BComPort1.Write(Data, SizeOf(Data));
end;
var r1,g1,b1:integer;
Data: Byte;
begin
r1:=GetRValue(i) shr 3;
g1:=GetGValue(i) shr 2;
b1:=GetBValue(i) shr 3;
i:= (r1 shl 11) + (g1 shl 5) + b1; // i - глобальная integer, из ColorDialog1
BComPort1.Open;
Data := Hi(i);
BComPort1.Write(Data, SizeOf(Data));
Data := Lo(i);
BComPort1.Write(Data, SizeOf(Data));
end;
Т.е. делим полученный цвет на 2 отдельных байта, Hi и Lo, и побайтно отправляем. Сначала первый, затем второй.
Я счастлив...!!! И это всё на ATMega8...
Теперь осталось разобраться с выводов изображения в заданную область и передачей текста в дисплей.
Единственное только картинка выводится ооочень долго, 4-5 сек, но я думаю это из-за скорости COM порта. Я поставил 38400. Надо будет увеличить. Потому что заливка экрана одним цветом происходила очень быстро, < 1сек.
P.S. Кстати, в диспетчере устройств для TUSB 3410 можно выставить максимум 128000 бит/сек. Хотя вроде бы производитель обещает гораздо больше, странно.
Цитата: mr_smit
Единственное только картинка выводится ооочень долго, 4-5 сек, но я думаю это из-за скорости COM порта. Я поставил 38400. Надо будет увеличить. Потому что заливка экрана одним цветом происходила очень быстро, < 1сек.
P.S. Кстати, в диспетчере устройств для TUSB 3410 можно выставить максимум 128000 бит/сек. Хотя вроде бы производитель обещает гораздо больше, странно.
P.S. Кстати, в диспетчере устройств для TUSB 3410 можно выставить максимум 128000 бит/сек. Хотя вроде бы производитель обещает гораздо больше, странно.
Узкое место скорее всего не в скорости порта, а в алгоритме вытаскивания и преобразования пикселей перед посылкой в порт. Можешь привести код отправки картинки?
Код:
procedure TForm1.Button1Click(Sender: TObject);
var r1,g1,b1:integer;
PixColor:integer;
i,j:integer;
Data: Byte;
begin
BComPort1.Open;
for i:=0 to Image1.Picture.Height-1 do
begin
for j:=0 to Image1.Picture.Width-1 do
begin
PixColor:= Image1.Canvas.Pixels[j,Image1.Picture.Height-1-i];
r1:=GetRValue(PixColor) shr 3;
g1:=GetGValue(PixColor) shr 2;
b1:=GetBValue(PixColor) shr 3;
PixColor:= (r1 shl 11) + (g1 shl 5) + b1;
Data := Hi(PixColor);
BComPort1.Write(Data, SizeOf(Data));
Data := Lo(PixColor);
BComPort1.Write(Data, SizeOf(Data));
end;
end;
end;
var r1,g1,b1:integer;
PixColor:integer;
i,j:integer;
Data: Byte;
begin
BComPort1.Open;
for i:=0 to Image1.Picture.Height-1 do
begin
for j:=0 to Image1.Picture.Width-1 do
begin
PixColor:= Image1.Canvas.Pixels[j,Image1.Picture.Height-1-i];
r1:=GetRValue(PixColor) shr 3;
g1:=GetGValue(PixColor) shr 2;
b1:=GetBValue(PixColor) shr 3;
PixColor:= (r1 shl 11) + (g1 shl 5) + b1;
Data := Hi(PixColor);
BComPort1.Write(Data, SizeOf(Data));
Data := Lo(PixColor);
BComPort1.Write(Data, SizeOf(Data));
end;
end;
end;
Код:
PixColor:= Image1.Canvas.Pixels[j,Image1.Picture.Height-1-i];
Это очень медленная операция. Копай в сторону TBitmap.Scanline. Кроме того, здесь вовсе не нужны вложенные циклы.
Цитата:
Это очень медленная операция.
У меня загрузка процессора не меняется вообще при выполнении этой операции. Как была 0-2% так и остается.
Цитата: mr_smit
А как с помощью Scanline добраться до цвета одного пикселя? Читал читал так и не понял.
Воспринимай Свойство Scanline как одномерный массив указателей на строки картинки. Сама строка представляет собой массив байт, значения которого зависят от формата изображения (например, для pf24, первые 3 байта этой строки кодируют первый пиксель строки в формате RGB).
В общем, должно получится что-то типа:
Код:
var line: PByteArray;
begin
line := Bitmap1.Scanline[0]; // Самая нижняя строка (строки нумеруются снизу вверх)
// R := line[0];
// G := line[1];
// B := line[2];
end;
begin
line := Bitmap1.Scanline[0]; // Самая нижняя строка (строки нумеруются снизу вверх)
// R := line[0];
// G := line[1];
// B := line[2];
end;
ЗЫ: Предензии по ошибкам не принимаются - Delphi не видел уже года 2 :rolleyes::D
Цитата:
У меня загрузка процессора не меняется вообще при выполнении этой операции. Как была 0-2% так и остается.
А при чем здесь процессор? Просто вызов функции GDI GetPixel (который скрывается под свойством TBitmap.Pixels) весьма тормозной.
Всё равно не понял. Как мне получить цвет TColor ?