![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
сжатие и отправкакартинки по сети
night_light © (2009-04-20 16:51:00)Здравствуйте, подскажите плиз оптимальный путь решения:
есть картинка в памяти (тип TBitmap), необходимо её сжать, чтобы передать по сети, передача несжатых изображений происходит слишком медленно, а передавать надо хотя бы 30 кадров в секунду. Во что лучше сжать, чтобы: 1) быстрее сжалось, 2) сжатое изображение было хотя бы в 5 раз меньше, 3) на приёмном конце прога на делфи относительно просто просто отобразила полученное изображение?
AIRDIGER (2009-04-21 15:26:00) [1]Жертвую из своих запасов... не гарантирую что подойдет ....как написал так написал ...
{---------------------------- CompressBufferToBuffer --------------------------}
function CompressBufferToBuffer(InBuffer: Pointer; szInBuffer: integer;
var OutBuffer; var OutBytes: Integer; Level: Shortint): Boolean;
var
Buffer: array [1..1024] of byte;
InMemStrm : TMemoryStream;
OutMemStrm : TMemoryStream;
CompressStrm : TCompressionStream;
ByteRaed : Integer;
begin
Result := false;
if (Not Assigned(InBuffer)) or (szInBuffer = 0) then Exit;
try
if Level > 3 then Level := 3;
if Level < 0 then Level := 0;
InMemStrm := TMemoryStream.Create;
OutMemStrm := TMemoryStream.Create;
CompressStrm := TCompressionStream.Create(TCompressionLevel(Level),OutMemStrm);
InMemStrm.Write(InBuffer^, szInBuffer);
if InMemStrm.Size = 0 then Exit;
InMemStrm.Position := 0;
repeat
ByteRaed := InMemStrm.Read(Buffer,1024);
CompressStrm.Write(Buffer,ByteRaed);
until ByteRaed < 1024;
if OutMemStrm.Size = 0 then Exit;
OutBytes := OutMemStrm.Size;
ReallocMem(Pointer(OutBuffer),OutBytes);
OutMemStrm.Position := 0;
OutMemStrm.Read(Pointer(OutBuffer)^,OutBytes);
Result := true;
finally
CompressStrm.Free;
InMemStrm.Free;
OutMemStrm.Free;
end;
end;
{--------------------------- DecompressBufferToBuffer -------------------------}
function DecompressBufferToBuffer(InBuffer: Pointer; szInBuffer: Integer;
var OutBuffer; var OutBytes: Integer): Boolean;
var
Buffer: array [1..1024] of byte;
InMemStrm : TMemoryStream;
OutMemStrm : TMemoryStream;
DecompressStrm : TDecompressionStream;
ByteRaed : Integer;
begin
Result := False;
if (Not Assigned(InBuffer)) or (szInBuffer = 0) then Exit;
try
InMemStrm := TMemoryStream.Create;
OutMemStrm := TMemoryStream.Create;
DecompressStrm := TDecompressionStream.Create(InMemStrm);
InMemStrm.Write(InBuffer^,szInBuffer);
if InMemStrm.Size = 0 then Exit;
InMemStrm.Position := 0;
repeat
ByteRaed := DecompressStrm.Read(Buffer,1024);
OutMemStrm.Write(buffer,ByteRaed);
until ByteRaed < 1024;
if OutMemStrm.Size = 0 then Exit;
OutBytes := OutMemStrm.Size;
ReallocMem(Pointer(OutBuffer), OutBytes);
OutMemStrm.Position := 0;
OutMemStrm.Read(POinter(OutBuffer)^,OutBytes);
Result := true;
finally
DecompressStrm.Free;
InMemStrm.Free;
OutMemStrm.Free;
end;
end;
аноним (2009-04-21 15:04:00) [2]>... гигабитной сети не хватает, вот и возникла проблемка.
Где же ты был во времена 14400 бит/с, тогда за такое на костре бы спалили
Сергей М. (2009-04-20 19:47:00) [3]
> Slym © (20.04.09 19:42) [22]
> сжатие скорее всго основано на детекте изменения
Сам-то понял что сказал ?)
Сжимается ведь та самая дельта, которая ужеявляется результатом ранееотработавшего алгоритма детекта ..
Т.е. алгоритм детекта подает на вход алгоритма сжатия готовые данные - мол, сожми так-то и так-то вот такие-то данные, о происхождении которых тебе, алгоритм сжатия, знать совершенно необязательно
Slym (2009-04-20 19:42:00) [4]Сергей М. © (20.04.09 17:42) [17]
смотрят вполне качественное IPTV
сжатие скорее всго основано на детекте изменения кадров или их части, а не тупое сжатие каждого кадра...
30 jpg в секунду камень нужен мощьный :)
тут сжатие jpg http://www.delphimaster.ru/cgi-bin/forum.pl?id=1227604925&n=4
очень медленно, быстрее детектить изменение сцены, но на аналоговых шумных камерах нужен хороший алгоритм детекта движения сцены
Игорь Шевченко (2009-04-20 17:57:00) [5]
> в компе 4-х канальная плата видеозахвата на 120 кадров в
> сек. суммарно
ну вот у платы наверняка есть мануал, в котором написано, как передавать видео, а не отдельные картинки. Если не написано, как конкретно передавать, то наверняка стоит ссылка на сайт производителя для обращения за более подробной информацией.
night_light (2009-04-20 17:56:00) [6]уже писал простенькую программку на это счёт, прикидывал, при передаче несжатой картинки через сокеты канал используется почти полностью, вывод - метод передачи сокетами содержит не очень большое количество служебной информации и неплохо использует канал. Если я не прав, поправьте, пожалуйста.
Но по поводу протокола, действительно всё равно, просто с сокетами уже работал.
Сергей М. (2009-04-20 17:51:00) [7]
> задача - сжать .. а на другом конце полученную картинку отобразить
Т.е. ты считаешь, что транспортная часть будущей "системы" на сквозную ее производительность никак не влияет ?
Иными словами, тебе фиолетово, какой сетевой транспортный протокол при этом использовать ?
night_light (2009-04-20 17:45:00) [8]
> Что за камера ?
аналоговая камера, 752 на 582, 30 кадров в секунду,
в компе 4-х канальная плата видеозахвата на 120 кадров в сек. суммарно,
в делфе компонент TVideoGrabber,
> Киношники блин. Слова "потоковое видео" остались за гранью
> понимания ?
остались за гранью временных рамок, совершенно некогда разбираться с достижениями прогресса, задача - сжать BMP, желательно одной функцией некой библиотечки, а на другом конце полученную картинку отобразить.
> А что сотворяешь-то ? Уж не Remote Desktop ли ?
отнюдь :) думал, это стандартная задача систем видеорнаблюдения :(
Сергей М. (2009-04-20 17:42:00) [9]
> лить понадобилось слишком быстро, гигабитной сети не хватает
Нынче люди с успехом смотрят вполне качественное IPTV, будучи подключенными к провайдеру по 10-мегабитному каналу, а тебе и гигабитного подключения не хватает)
night_light (2009-04-20 17:38:00) [10]
> Насколько я понимаю это не отдельные и изображения, а что-
> то вроде фильма. Так и метод нужно использовать соответствующий.
> Я слышал краем уха, что для этого используют сжатие с потерями
> mpeg. Получается файл avi, если я не путаю.
совершенно правильно понимаете.
но я не знаю, как фильм передавать по сети, а с картинками всё проще,
лью себе через сокеты одну за другой, и всего делов.
но лить понадобилось слишком быстро, гигабитной сети не хватает, вот и возникла проблемка.
Сергей М. (2009-04-20 17:37:00) [11]
> передаётся реальная картинка с камеры
Что за камера ?
Может ты вообще не тот огород окучиваешь ?)
Игорь Шевченко (2009-04-20 17:35:00) [12]Киношники блин. Слова "потоковое видео" остались за гранью понимания ?
Сергей М. (2009-04-20 17:34:00) [13]А что сотворяешь-то ? Уж не Remote Desktop ли ?
night_light (2009-04-20 17:33:00) [14]GIF не подходит, сжатие без потерь в моём случае малоэффективно,
передаётся реальная картинка с камеры. И точно повторяющихся участков не будет.
> uses ZLib, TCompressionStream
Спасибо! Такой вопрос, а переменная какого типа хранит в памяти JPEG?
(BMP файл, как я понял, хранится в TBitmap)
И еще, JPEG выводить в Image сразу, без обратной обработки?
Я пока выводил только BMP в виде TBitmap.
palva (2009-04-20 17:33:00) [15]Насколько я понимаю это не отдельные и изображения, а что-то вроде фильма. Так и метод нужно использовать соответствующий. Я слышал краем уха, что для этого используют сжатие с потерями mpeg. Получается файл avi, если я не путаю. Анимированный gif, конечно, тоже можно использовать, но он сжимает без потерь, а значит сохраняет много нюансов, которые можно не сохранять, поскольку они незаметны.
Сергей М. (2009-04-20 17:31:00) [16]
> компонент .. может выдавать
> либо TBitmap в память
Этого достаточно.
Режешь битмап тек.кадра на прямоугольные "куски" сравнительно небольшого размера, сравниваешь содержимое каждого "куска" с содержимым соотв. "куска" битмапа предыдущего кадра. При обнаружении несовпадения жмешь изменившийся "кусок", снабжаешь инф.пакет со сжатым "куском" заголовком, отражающим технологические атрибуты "куска" (время, координаты и размер, алг-м сжатия т.п.) и отправляешь инф.пакет приемнику. Имея эту инф-цию приемник проделывает в той же последовательности обратные действия, позволяющие отразить поступившие изменения в некоем своем битмапе.
night_light (2009-04-20 17:21:00) [17]> Сергей М. © (20.04.09 17:05) [5]
> > Остаётся понять, как сжатьСмотря что ты передаешь и что
> хочешь получить на принимающей стороне... Т.е. какого характера
> изменяющееся изображение передается и какого качества изображение
> должно быть восстановлено на принимающей стороне...В простейшем
> случае для незначительно меняющегося во времени изображения
> вполне может подойти и RLE-алгоритм компрессии/декомпрессии.
>
По поводу качества, при сжатии в JPEG фотошопом с уменьшением размера файла где-то в 10 раз, получается картинка с вполне удовлетворяющим в этой задаче качеством.
Вопрос ещё, насколько быстро будет производится JPEG-сжатие? Разрешение 752 на 582, 24 бита на цвет.
clickmaker (2009-04-20 17:15:00) [18]uses ZLib, TCompressionStream
Palladin (2009-04-20 17:13:00) [19]gif
night_light (2009-04-20 17:11:00) [20]TBitmap формат тяжёлый, согласен,
но компонент видеозахвата, который я использую, может выдавать либо TBitmap в память, либо BMP или JPEG, но уже в виде файла для сохранения, а мне нужно передать по сети на другую прогу и там отобразить.
Может можно как-нибудь сохранять, но в память, а оттуда уже передавать по сети на другой комп и там отображать?
И если всё таки конвертировать из TBitmap в другой формат, сжатый, но хранимый в памяти, то во что лучше? Чтобы на приёмном конце не пришлось делать декомпрессию, а как и с TBitmap-ом - просто вывести на Image или некий другой графический компонент.