Текущий архив: 2009.06.07;
Скачать: CL | DM;
Внизсжатие и отправкакартинки по сети Найти похожие ветки
← →
night_light © (2009-04-20 16:51) [0]Здравствуйте, подскажите плиз оптимальный путь решения:
есть картинка в памяти (тип TBitmap), необходимо её сжать, чтобы передать по сети, передача несжатых изображений происходит слишком медленно, а передавать надо хотя бы 30 кадров в секунду. Во что лучше сжать, чтобы: 1) быстрее сжалось, 2) сжатое изображение было хотя бы в 5 раз меньше, 3) на приёмном конце прога на делфи относительно просто просто отобразила полученное изображение?
← →
clickmaker © (2009-04-20 16:56) [1]ZLib, например.
Или TJPegImage или Intel Jpeg Library
в любом случае, TBitmap - не оптимальный вариант
← →
Сергей М. © (2009-04-20 16:58) [2]
> есть картинка в памяти (тип TBitmap)
Значит наверняка есть и предыдущая картинка, сделанная на 1/30 секунды ранее.
Остается сравнить эти две картинки, локализовать области, подверженные изменениям, сжать эти изменения и передать приемнику.
Трансляция изменений в подавляющем большинстве случаев несравнимо производительней, чем передачи готовых картинок.
← →
night_light © (2009-04-20 17:01) [3]
> Сергей М. © (20.04.09 16:58) [2]
> > есть картинка в памяти (тип TBitmap)Значит наверняка есть
> и предыдущая картинка, сделанная на 1/30 секунды ранее.Остается
> сравнить эти две картинки, локализовать области, подверженные
> изменениям, сжать эти изменения и передать приемнику.Трансляция
> изменений в подавляющем большинстве случаев несравнимо производительней,
> чем передачи готовых картинок.
Спасибо, идея хорошая. Остаётся понять, как сжать. :)
← →
Palladin © (2009-04-20 17:04) [4]... а, все таки, почему телеграммы из воды сухие выходят
← →
Сергей М. © (2009-04-20 17:05) [5]
> Остаётся понять, как сжать
Смотря что ты передаешь и что хочешь получить на принимающей стороне...
Т.е. какого характера изменяющееся изображение передается и какого качества изображение должно быть восстановлено на принимающей стороне...
В простейшем случае для незначительно меняющегося во времени изображения вполне может подойти и RLE-алгоритм компрессии/декомпрессии.
← →
night_light © (2009-04-20 17:11) [6]TBitmap формат тяжёлый, согласен,
но компонент видеозахвата, который я использую, может выдавать либо TBitmap в память, либо BMP или JPEG, но уже в виде файла для сохранения, а мне нужно передать по сети на другую прогу и там отобразить.
Может можно как-нибудь сохранять, но в память, а оттуда уже передавать по сети на другой комп и там отображать?
И если всё таки конвертировать из TBitmap в другой формат, сжатый, но хранимый в памяти, то во что лучше? Чтобы на приёмном конце не пришлось делать декомпрессию, а как и с TBitmap-ом - просто вывести на Image или некий другой графический компонент.
← →
Palladin © (2009-04-20 17:13) [7]gif
← →
clickmaker © (2009-04-20 17:15) [8]uses ZLib, TCompressionStream
← →
night_light © (2009-04-20 17:21) [9]> Сергей М. © (20.04.09 17:05) [5]
> > Остаётся понять, как сжатьСмотря что ты передаешь и что
> хочешь получить на принимающей стороне... Т.е. какого характера
> изменяющееся изображение передается и какого качества изображение
> должно быть восстановлено на принимающей стороне...В простейшем
> случае для незначительно меняющегося во времени изображения
> вполне может подойти и RLE-алгоритм компрессии/декомпрессии.
>
По поводу качества, при сжатии в JPEG фотошопом с уменьшением размера файла где-то в 10 раз, получается картинка с вполне удовлетворяющим в этой задаче качеством.
Вопрос ещё, насколько быстро будет производится JPEG-сжатие? Разрешение 752 на 582, 24 бита на цвет.
← →
Сергей М. © (2009-04-20 17:31) [10]
> компонент .. может выдавать
> либо TBitmap в память
Этого достаточно.
Режешь битмап тек.кадра на прямоугольные "куски" сравнительно небольшого размера, сравниваешь содержимое каждого "куска" с содержимым соотв. "куска" битмапа предыдущего кадра. При обнаружении несовпадения жмешь изменившийся "кусок", снабжаешь инф.пакет со сжатым "куском" заголовком, отражающим технологические атрибуты "куска" (время, координаты и размер, алг-м сжатия т.п.) и отправляешь инф.пакет приемнику. Имея эту инф-цию приемник проделывает в той же последовательности обратные действия, позволяющие отразить поступившие изменения в некоем своем битмапе.
← →
palva © (2009-04-20 17:33) [11]Насколько я понимаю это не отдельные и изображения, а что-то вроде фильма. Так и метод нужно использовать соответствующий. Я слышал краем уха, что для этого используют сжатие с потерями mpeg. Получается файл avi, если я не путаю. Анимированный gif, конечно, тоже можно использовать, но он сжимает без потерь, а значит сохраняет много нюансов, которые можно не сохранять, поскольку они незаметны.
← →
night_light © (2009-04-20 17:33) [12]GIF не подходит, сжатие без потерь в моём случае малоэффективно,
передаётся реальная картинка с камеры. И точно повторяющихся участков не будет.
> uses ZLib, TCompressionStream
Спасибо! Такой вопрос, а переменная какого типа хранит в памяти JPEG?
(BMP файл, как я понял, хранится в TBitmap)
И еще, JPEG выводить в Image сразу, без обратной обработки?
Я пока выводил только BMP в виде TBitmap.
← →
Сергей М. © (2009-04-20 17:34) [13]А что сотворяешь-то ? Уж не Remote Desktop ли ?
← →
Игорь Шевченко © (2009-04-20 17:35) [14]Киношники блин. Слова "потоковое видео" остались за гранью понимания ?
← →
Сергей М. © (2009-04-20 17:37) [15]
> передаётся реальная картинка с камеры
Что за камера ?
Может ты вообще не тот огород окучиваешь ?)
← →
night_light © (2009-04-20 17:38) [16]
> Насколько я понимаю это не отдельные и изображения, а что-
> то вроде фильма. Так и метод нужно использовать соответствующий.
> Я слышал краем уха, что для этого используют сжатие с потерями
> mpeg. Получается файл avi, если я не путаю.
совершенно правильно понимаете.
но я не знаю, как фильм передавать по сети, а с картинками всё проще,
лью себе через сокеты одну за другой, и всего делов.
но лить понадобилось слишком быстро, гигабитной сети не хватает, вот и возникла проблемка.
← →
Сергей М. © (2009-04-20 17:42) [17]
> лить понадобилось слишком быстро, гигабитной сети не хватает
Нынче люди с успехом смотрят вполне качественное IPTV, будучи подключенными к провайдеру по 10-мегабитному каналу, а тебе и гигабитного подключения не хватает)
← →
night_light © (2009-04-20 17:45) [18]
> Что за камера ?
аналоговая камера, 752 на 582, 30 кадров в секунду,
в компе 4-х канальная плата видеозахвата на 120 кадров в сек. суммарно,
в делфе компонент TVideoGrabber,
> Киношники блин. Слова "потоковое видео" остались за гранью
> понимания ?
остались за гранью временных рамок, совершенно некогда разбираться с достижениями прогресса, задача - сжать BMP, желательно одной функцией некой библиотечки, а на другом конце полученную картинку отобразить.
> А что сотворяешь-то ? Уж не Remote Desktop ли ?
отнюдь :) думал, это стандартная задача систем видеорнаблюдения :(
← →
Сергей М. © (2009-04-20 17:51) [19]
> задача - сжать .. а на другом конце полученную картинку отобразить
Т.е. ты считаешь, что транспортная часть будущей "системы" на сквозную ее производительность никак не влияет ?
Иными словами, тебе фиолетово, какой сетевой транспортный протокол при этом использовать ?
← →
night_light © (2009-04-20 17:56) [20]уже писал простенькую программку на это счёт, прикидывал, при передаче несжатой картинки через сокеты канал используется почти полностью, вывод - метод передачи сокетами содержит не очень большое количество служебной информации и неплохо использует канал. Если я не прав, поправьте, пожалуйста.
Но по поводу протокола, действительно всё равно, просто с сокетами уже работал.
← →
Игорь Шевченко © (2009-04-20 17:57) [21]
> в компе 4-х канальная плата видеозахвата на 120 кадров в
> сек. суммарно
ну вот у платы наверняка есть мануал, в котором написано, как передавать видео, а не отдельные картинки. Если не написано, как конкретно передавать, то наверняка стоит ссылка на сайт производителя для обращения за более подробной информацией.
← →
Slym © (2009-04-20 19:42) [22]Сергей М. © (20.04.09 17:42) [17]
смотрят вполне качественное IPTV
сжатие скорее всго основано на детекте изменения кадров или их части, а не тупое сжатие каждого кадра...
30 jpg в секунду камень нужен мощьный :)
тут сжатие jpg http://delphimaster.net/view/6-1227604925/
очень медленно, быстрее детектить изменение сцены, но на аналоговых шумных камерах нужен хороший алгоритм детекта движения сцены
← →
Сергей М. © (2009-04-20 19:47) [23]
> Slym © (20.04.09 19:42) [22]
> сжатие скорее всго основано на детекте изменения
Сам-то понял что сказал ?)
Сжимается ведь та самая дельта, которая уже является результатом ранее отработавшего алгоритма детекта ..
Т.е. алгоритм детекта подает на вход алгоритма сжатия готовые данные - мол, сожми так-то и так-то вот такие-то данные, о происхождении которых тебе, алгоритм сжатия, знать совершенно необязательно
← →
аноним (2009-04-21 15:04) [24]>... гигабитной сети не хватает, вот и возникла проблемка.
Где же ты был во времена 14400 бит/с, тогда за такое на костре бы спалили
← →
AIRDIGER © (2009-04-21 15:26) [25]Жертвую из своих запасов... не гарантирую что подойдет ....как написал так написал ...
{---------------------------- 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;
Страницы: 1 вся ветка
Текущий архив: 2009.06.07;
Скачать: CL | DM;
Память: 0.57 MB
Время: 0.005 c