Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Delphi пример пересылки изображения через сеть


Страницы:   1 2

Knight ©   (2004-11-07 01:25:00) 

У кого может завалялся? (ServerSocket-ClientSocket)


able   (2004-11-10 00:36:00) [1]

Странно. Видел пару чатов, работающих на NMUDP и ничего вроде..


Verg   (2004-11-09 21:06:00) [2]

Вот попробуй для прикола. Особенно впечатляет, когда не из под Дельфи запускаешь exe-шник и нажимешь Button2  :)

procedure TForm1.Button2Click(Sender: TObject);
var ms:TMemoryStream;
   S : string;
begin
ms:=TMemoryStream.Create;
try
 Setlength(S, 5000);
 Ms.WriteBuffer(S[1], length(S));
 NMUDP1.SendStream(Ms);
finally
  Ms.Free;
end;
end;



> А глюки переходят от версии к версии или их правят? (Delphi
> 6)


Помоему Borland вообще "забил" на FastNet. Для меня, например, решающим в свое время стал факт отсутствия исходников.


Knight   (2004-11-09 20:58:00) [3]


> [19] Verg ©   (09.11.04 20:51)
> Кстати, в NMUDP -шном SendStream был како-то "замечательный"
> глюк.

А глюки переходят от версии к версии или их правят? (Delphi 6)


Verg   (2004-11-09 20:51:00) [4]

Кстати, в NMUDP -шном SendStream был како-то "замечательный" глюк.
Когда-то даже разбирался в чем дело. Что-то там с буферами фиксированного (небольшого) размера, расположенными в стеке для чтения из потока.  
При размере передаваемого потока больше некоторой величины (2048 байт, что ли) весь процесс с "грохотом" рухал по причине затирания стека содержимым потока...


Knight   (2004-11-09 20:39:00) [5]


> [17] Verg ©   (09.11.04 20:07)

Всё пошло... я на приёме данных Buff^ сделал, а на отправке изменить забыл... вот он в ссылках и запутался :)))

СПАСИБО.


Verg   (2004-11-09 20:07:00) [6]


> Кстати, он и не должен так работать, т.к. Buffer это указатель,
> а у меня PChar... т.е. всё верно... пример нашёл в хэлпе,
> один к одному... но не пашет :(


Честно говоря не понял что ты сказал.

У тебя Buff - это pchar, т.е. указатель.

TMemoryStrea.Read( var Buffer; Count : integer);

Т.е. Buffer - это ссылка.

Поэтому,

ms.Read(Buff^,NumberBytes);

можно и
ms.Read(Buff[0], NumberBytes);
что есть суть одно и тоже

И никак иначе!

Кстати, в Help-e пример вообще с string-ом, а не с pchar.


Knight   (2004-11-09 19:56:00) [7]


> [14] Verg ©   (09.11.04 16:51)
> > //    ms.Read(Buff^,NumberBytes);

Кстати, он и не должен так работать, т.к. Buffer это указатель, а у меня PChar... т.е. всё верно... пример нашёл в хэлпе, один к одному... но не пашет :(


Knight   (2004-11-09 19:31:00) [8]


> [14] Verg ©   (09.11.04 16:51)
> > //    ms.Read(Buff^,NumberBytes);

Так вообще не работает... у меня хоть в Buff данные, а тут мусор...


Verg   (2004-11-09 16:51:00) [9]

Для начала

> //    ms.Read( Buff^,NumberBytes);


Knight   (2004-11-09 16:23:00) [10]

В чём проблема? Стоит раскомментировать строку с Read... как начинается сбой по памяти... причём в Buff верное значение полученной строки... но при этом ms.Free начинает вызываться 2 раза подряд.

procedure TMainForm.NMUDPDataReceived(Sender: TComponent; NumberBytes: Integer; FromIP: String; Port: Integer);
var ms:TMemoryStream;
   Buff:PChar;
begin
 ms:=TMemoryStream.Create;
 try
   NMUDP.ReadStream(ms);
   Buff:=AllocMem(NumberBytes+1);
   ms.Position:=0;
//    ms.Read(Buff,NumberBytes);
   FreeMem(Buff);
 finally
   ms.Free;
 end;
end;


VMcL   (2004-11-09 07:22:00) [11]

>> Knight ©  (08.11.04 16:32) [11]

Боюсь, с изображением такой "номер" не прокатит. Разве что, если его закодировать, например, в BASE64. Только нужно иметь в виду, что в BASE64 данные на ~33% больше занимать будут.


Knight   (2004-11-08 16:32:00) [12]


> [10] VMcL ©   (08.11.04 07:31)
> Пример маркера - это HTTP запрос. Признаком конца заголовка
> запроса служит двойной перевод каретки (#10#10, если не
> ошибаюсь);

А это мысль... так и сделаю.

Всем, СПАСИБО! :)


VMcL   (2004-11-08 07:31:00) [13]

>> Knight ©  (07.11.04 21:32) [9]

Если прикручивать инфу "сколько", то это метод [3], [4]. Пример маркера - это HTTP запрос. Признаком конца заголовка запроса служит двойной перевод каретки (#10#10, если не ошибаюсь); и это работает корректно, потому что в самом заголовке такая последовательность встретиться не может.


Knight   (2004-11-07 21:32:00) [14]


>  [8] VMcL ©   (07.11.04 20:49)
> Некоторая последовательность бит, которая не может встретиться
> в передаваемых данных.

Т.е. в начале данных прикручивать инфу о том, что это и сколько этого должно быть? Если да, то я эту мысль уже думаю... %)


VMcL   (2004-11-07 20:49:00) [15]

>> Knight ©  (07.11.04 16:11) [7]

Некоторая последовательность бит, которая не может встретиться в передаваемых данных.


Knight   (2004-11-07 16:11:00) [16]


> [6] VMcL ©   (07.11.04 13:08)
> Необязательно. Можно, например, пользоваться маркером.

А это что такое? Первый раз слышу...


VMcL   (2004-11-07 13:08:00) [17]

>> Knight ©  (07.11.04 04:08) [5]

Необязательно. Можно, например, пользоваться маркером.


Knight   (2004-11-07 04:08:00) [18]


> [3] PEAKTOP ©   (07.11.04 03:45)

Пример, на базе которого это сделано я нашёл... поэтому вопрос и появился... неужели нельзя как-то иначе? Обязательно, сперва отправлять размер, а потом склеивать Socket.ReceiveText'ы?


PEAKTOP   (2004-11-07 03:50:00) [19]

а потом на клиенте читал:


implementation
uses
 jpeg;
.....
var
 RecivingDesktop :Boolean = false;
.....

procedure TZeandgePropertiesForm.ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket);
var
 s, sl :string;
 count :longint;
begin
s:= Socket.ReceiveText;
if not RecivingDesktop then
 begin
 count            := 0;
 Gauge.Visible    := FALSE;
 Label1.Caption := '';
 SetLength(sl, StrLen(PChar(s))+1);          // +1 for the null terminator
 StrLCopy(@sl[1], PChar(s), Length(sl)-1);
 DataSize         := StrToInt(sl);
 Data             := TMemoryStream.Create;    
 Delete(s, 1, Length(sl));
 RecivingDesktop := TRUE;
 end;
try
 count := count + 1;
 Data.Write(s[1], length(s));
 Gauge.Progress := Round(count/DataSize*100);
 Gauge.Visible  := TRUE;
 Label1.Caption := 'reciving data ....';
 if Data.Size = DataSize then
   begin
   Gauge.Visible := FALSE;
   Data.Position := 0;
   DesktopImage.Picture.Graphic := TJPEGImage.Create;
   DesktopImage.Picture.Graphic.LoadFromStream(Data);
   DesktopImage.Width   := DesktopImage.Picture.Graphic.Width;
   DesktopImage.Height  := DesktopImage.Picture.Graphic.Height;
   RecivingDesktop := FALSE;
   Socket.Close;
   Label1.Caption := 'READY !';
   end;
except
 Data.Free;
end;
end;


PEAKTOP   (2004-11-07 03:45:00) [20]

1) Делаешь скрин-шот десктопа (смотри ФАК)
2) Сжимаешь ее на клиенте в jpeg
3) Передаешь jpeg по сети потоком.

Я когда-то  делал так:

implementation
uses
 jpeg;

........

procedure TMainForm.ServerSocketClientRead(
 Sender: TObject; Socket: TCustomWinSocket);
var
 ms  :TMemoryStream;
 jpg :TJPEGImage;
 img :TImage;
 DC  :HDC;
 s   :string;
begin
if Socket.ReceiveText='PHOTO' then
 try
   ms         := TMemoryStream.Create;
   img        := TImage.Create(NIL);
   img.Picture.Bitmap.Height := Screen.Height;
   img.Picture.Bitmap.Width  := Screen.Width;
   DC         := GetDC(HWND_DESKTOP);
   bitblt(img.Picture.Bitmap.Canvas.Handle, 0,0, Screen.Width, Screen.Height, DC, 0, 0, SRCCOPY);
   jpg        := TJPEGImage.Create;
   jpg.Assign(img.Picture.Bitmap);
   img.Free;
   jpg.Compress;
   jpg.SaveToStream(ms);
   ms.Position:= 0;
   Socket.SendText(IntToStr(ms.Size) + #0);
   Socket.SendStream(ms);
   jpg.Free;
  except
   ms.Free;
  end;
end;


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо