Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2011.10.16;
Скачать: [xml.tar.bz2];

Вниз

Использ. ZLIB для сжатия файла при передаче сервер-клиент   Найти похожие ветки 

 
Pcrepair ©   (2011-06-28 19:07) [0]

Использование библиотеки Zlib для компрессии-декомпрессии графического файла (BMP) при передаче по сети с использованием архитекруры сервер-клиент на базе INDY10

Есть сервер, делает  по запросу клиента захват видеобуфера в формат BMP, записывает в ОЗУ, и передает через сетевой сокет клиенту. Проблема в том что сетевой адаптер загружается по максимуму (частота обращения к серверу 40 мс). надо както сжать передаваемые по сети данные.
вот код сервера (немного упрощенная версия, все лишнее отброшено)

unit main;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, IdContext, StdCtrls, IdBaseComponent, IdComponent, IdCustomTCPServer,
 IdTCPServer, ExtCtrls, Zlib;

type
 TForm1 = class(TForm)
   IdTCPServer1: TIdTCPServer;
   IPadress: TEdit;
   PortNumber: TEdit;
   Button1: TButton;
   Memo1: TMemo;
   Image1: TImage;
   procedure Button1Click(Sender: TObject);
   procedure IdTCPServer1Execute(AContext: TIdContext);
   //procedure Compress(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
   procedure Log(S:string);
   procedure GET_SCREEN;
 end;

var
 Form1: TForm1;
 pic : TMemoryStream; //ГлобПЕРЕМ в которой хранится данные скрина экрана

implementation

{$R *.dfm}

procedure TForm1.GET_SCREEN; //Процедура получения скрина экрана
var
 Desktop: TCanvas;
 B: TBitmap;
 W, H :Integer;
 Kursor:TPoint;
 TempRect:TRect;
begin
GetCursorPos(Kursor);
W:=Screen.Width;
H:=screen.Height;
TempRect:=Rect(Kursor.x,Kursor.y,Kursor.x+10,Kursor.y+10);
B:=TBitmap.Create;
B.Width:=W;
B.Height:=H;

Desktop:=TCanvas.Create;
try
 with Desktop do
  Handle := GetWindowDC(GetDesktopWindow);
  with B.Canvas do
   begin
    Brush.Color:=clGreen;
    CopyRect (Rect (0, 0, w, h),
              DeskTop,
              Rect (0, 0, w, h));
    FillRect(TempRect);
   end;
  FreeAndNil(pic);
  pic := TMemoryStream.create; //вот тут данные размещаются в ОЗУ
    B.SaveToStream(pic);
finally
 DeskTop.Free;
 B.Free;
end;
end;

procedure TForm1.IdTCPServer1Execute(AContext: TIdContext); //Процедура передачи данных клиенту
var
 z: string;
 X,Y:integer;

 K:TPoint;
begin
 with AContext.Connection do
 begin
  z := AContext.Connection.IOHandler.ReadLn;
  if SameText(Copy(z, 1, 11), "get_screen ") then
  begin
   Log("Запрошен скриншот");
   GET_SCREEN;
     AContext.Connection.IOHandler.WriteBufferOpen(pic.Size);
   Log("Передаем файл s.bmp");

   AContext.Connection.IOHandler.Write(pic);
   Log("Файл передан");
   AContext.Connection.IOHandler.Close;
  end;

  if SameText(Copy(z, 1, 11), "mouse_move ") then
  begin
   z := AContext.Connection.IOHandler.ReadLn;
   if SameText(Copy(z, 1, 8), "mouse_x ") then
   X:=StrToInt(Copy(z,9,4));

   z := AContext.Connection.IOHandler.ReadLn;
   if SameText(Copy(z, 1, 8), "mouse_y ") then
   Y:=StrToInt(Copy(z,9,4));

   Log("Перемещение мыши");
   SetCursorPos(X,Y);
 end;

 if SameText(Copy(z, 1, 11), "mouse_left ") then
  begin
   GetCursorPos(K);
   mouse_event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTDOWN,K.X,K.Y,0,0);
   mouse_event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTUP,K.X,K.Y,0,0);
   Log("Нажатие левой кнопки мыши");
  end;

  if SameText(Copy(z, 1, 12), "mouse_right ") then
  begin
   GetCursorPos(K);
   mouse_event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_RIGHTDOWN,K.X,K.Y,0,0);
   mouse_event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_RIGHTUP,K.X,K.Y,0,0);
   Log("Нажатие правой кнопки мыши");
  end;

 AContext.Connection.Disconnect;
end;
end;
end.


В общем и целом все работает
Вопрос:
как тут прикрутить сжатие ПЕРЕМ pic в момент передачи ее клиенту по сети с помощью TCompressionStream от ZLib.pas
использование трансформации *.bmp в другие форматы типа *.png не обсуждается, нужен формат файла BMP (для последующей обработки OCR)


 
Ega23 ©   (2011-06-28 19:12) [1]


> как тут прикрутить сжатие ПЕРЕМ pic в момент передачи ее
> клиенту по сети с помощью TCompressionStream от ZLib.pas

Взять и сжать, какие проблемы-то?
З.Ы. Код - Адъ и Содомiя


 
Pcrepair ©   (2011-06-28 19:21) [2]

вижу, ЕГА23, ты сильно продвинутая
напиши код, если все так просто


 
Ega23 ©   (2011-06-28 19:36) [3]


> вижу, ЕГА23, ты сильно продвинутая


Да, я такая


> напиши код, если все так просто


1. Версия delphi не указана. А различия в использовании ZLib.pas есть. Небольшие, но есть.
2. Я по вторникам не подаю.
3. with AContext.Connection do
begin
 z := AContext.Connection.IOHandler.ReadLn;

Жжош напалмом.


 
Pcrepair ©   (2011-06-28 19:38) [4]

ну не можеш или не хочешь чего в ветку "начинающим" влезла?
иди уже к продвинутым с ними меряйся чем там у тебя


 
Ega23 ©   (2011-06-28 19:43) [5]


> иди уже к продвинутым с ними меряйся чем там у тебя


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


 
Pcrepair ©   (2011-06-28 19:57) [6]

тебе было сказано куда идти, а не что делать
че то в голове у тебя все спуталось, а может ты буквы читать не умеешь?


 
Ega23 ©   (2011-06-28 20:04) [7]


> тебе было сказано куда идти, а не что делать


1. Малыш. Тебе уже было сказано, что без озвучивания версии Delphi твой вопрос несколько некорректен.
2. ZCompressStream-ZDecompressStream под D2010 работает с ошибкой. При упаковке определённого бинарника с сжатием по-умолчанию, при его последующей распаковке вылетает ошибка. Бинарник могу привести в качестве примера. Это из-за глюка самой ZLib. Лично я использовала ZCompress/ZDecompress, пока ошибок не встретилось.
3. Да, я не умею читать, не умею писать, в голове моей опилки. А что такое буквы?


 
Pcrepair ©   (2011-06-28 20:22) [8]

если бы бландинки были повнимательнее, оне бы заметили ужастные буквы INDY10 в самом начале темы. впрочем бландинки могуть и не знать что INDY10 входит в комплект D2010
и откуда взялось
> ZCompressStream-ZDecompressStream под D2010 работает с ошибкой

в теории сказано:
Модуль Zlib.pas предоставляет нам два класса-потока:
TCompressionStream Х TDecompressionStream
придумываем на ходу?


 
antonn (work)   (2011-06-28 20:28) [9]

попробуй http://desksoft.ru/index.php?forum&p_id=1062#post_1062
Ega23 - не она


 
Ega23 ©   (2011-06-28 20:36) [10]


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


Если бы мальчики Алексеи были повнимательнее, то увидели бы значок © возле моего ника, нажав на который прочитали бы, что зовут меня Егоров Олег Вячеславович и мне 35 лет. Но тебя же никто не заставляет такой квест проходить, нес па?
А что касается INDY10, то я вот точно такую же директорию наблюдаю у себя в сорцах и к 2007 и к 2010. Что на мой взгляд вполне может быть, т.к. INDY это INDY, а DELPHI это DELPHI.

> Модуль Zlib.pas предоставляет нам два класса-потока:

Тебе уже несколько раз сказали, что нужно версию Delphi указать. Разные zlib.pas у них, понимаешь? РАЗ-НЫ-Е.
Для 2007:
 TCustomZlibStream = class(TStream)
 TCompressionStream = class(TCustomZlibStream)
 TDecompressionStream = class(TCustomZlibStream)


Для 2010:
кроме классов ещё и
procedure ZCompressStream(inStream, outStream: TStream;
 level: TZCompressionLevel = zcDefault); overload;
// CG: Add overload to take old enum type
procedure ZCompressStream(inStream, outStream: TStream;
 level: TCompressionLevel); overload; inline;

procedure ZDecompressStream(inStream, outStream: TStream);


Впрочем, надоело.


 
Pcrepair ©   (2011-06-28 20:42) [11]

antonn (work), спасибо за наводку
там что? удаленный доступ к хосту через ВЕБ-интерфейс?

но мне нужны не сами процедуры компресии-декомпресии (их примеров есть много), мне неясно как содержимое ОЗУ в ПЕРЕМ pic сжать в момент передачи потока в сокет
ну ясно, надо написать саму процедуру с использованием модуля Zlib (надеюсь с ним все нормально, без глюков), затем... вызвать эту процедуру....
надо.... тут неясно как обернуть ПЕРЕМ этой процедурой. как все это написать. синтаксис


 
antonn (work)   (2011-06-28 20:45) [12]

там просто сайт.
я использую две функции для упаковки/распаковки, передается в tmemorystream, возвращается уже сжатый, это надо?


 
Ega23 ©   (2011-06-28 20:48) [13]


> я использую две функции для упаковки/распаковки, передается
> в tmemorystream, возвращается уже сжатый, это надо?


Ты сам стрим пакуешь, или его Memory? Там реальный косяк есть, я на него в начале года наткнулся.


 
antonn (work)   (2011-06-28 20:53) [14]

то, что сжимается через TCompressionStream


 
Pcrepair ©   (2011-06-28 20:55) [15]

antonn (work)
нет наверно, не это
еще раз
сервер по запросу клиента получает скрин экрана
сервер размещает полученный поток данных в ОЗУ

FreeAndNil(pic); // тут обнуляется и удаляется предыдущие данные в ОЗУ
  pic := TMemoryStream.create;// тут создаем ПЕРМ
    B.SaveToStream(pic);  //вот тут данные размещаются в ОЗУ

сервер передает данные в клиент

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


 
antonn (work)   (2011-06-28 20:57) [16]

FreeAndNil(pic); // тут обнуляется и удаляется предыдущие данные в ОЗУ
pic := TMemoryStream.create;// тут создаем ПЕРМ
B.SaveToStream(pic);
Pack_Memory(B);
посылаем в сеть B.


 
antonn (work)   (2011-06-28 20:58) [17]

не то скопипастил :)
FreeAndNil(pic); // тут обнуляется и удаляется предыдущие данные в ОЗУ
pic := TMemoryStream.create;// тут создаем ПЕРМ
B.SaveToStream(pic);
Pack_Memory(pic);
посылаем в сеть pic.CODE>


 
antonn (work)   (2011-06-28 21:00) [18]

хочу заметить что вот этот вот Pack_Memory() ниразу не оптимален внутрях


 
Pcrepair ©   (2011-06-28 21:13) [19]

ага....
то есть
Pack_Memory - это та самая процедура, которую еще надо написать, чтоб нормально еще и работала, которая вызывается и которая сжимает поток pic?

что касается -
> вот этот вот Pack_Memory() ниразу не оптимален внутрях

но работать то будет? оптимизация - следующий этап
Я уже заметил что эти простенькие программы (сервер и клиент) при работе жрут до 30% мощности ПРОЦА (интел4 два ведра)
узкие места будем разбирать отдельно


 
Anatoly Podgoretsky ©   (2011-06-28 21:22) [20]


> 2. Я по вторникам не подаю.

Пусть приходит в пятницую



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2011.10.16;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.003 c
15-1308767885
alexdn
2011-06-22 22:38
2011.10.16
Шаблон для ms sql


15-1308953060
Kerk
2011-06-25 02:04
2011.10.16
Quake2 to Delphi conversion


4-1217632047
sssyura
2008-08-02 03:07
2011.10.16
SHGetSpecialFolderPath


4-1251292381
Bora
2009-08-26 17:13
2011.10.16
Перехват событий от мыши в любом месте экрана


2-1308682465
antonn
2011-06-21 22:54
2011.10.16
Сменить ресурс в EXE





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский