Определить Eof для изображений JPG - PullRequest
20 голосов
/ 03 января 2011

Я посылаю много изображений с моего сервера клиенту последовательно через TCP. Теперь на клиенте, как мне эффективно определить, что это конец моего единственного изображения, запишите его в файловую систему, а затем на следующее изображение и т. Д. .

С уважением, ...

Ответы [ 3 ]

31 голосов
/ 06 января 2011

Ну, нет никакой гарантии, что вы не найдете FFD9 внутри изображения JPEG. Лучший способ найти конец изображения в формате JPEG - это проанализировать его. За каждым маркером, кроме FFD0 – FFD9 и FF01 (зарезервировано), сразу же следует спецификатор длины, который даст вам длину этого сегмента маркера, включая спецификатор длины, но не маркер. FF00 не является маркером, но для ваших целей вы можете рассматривать его как маркер без спецификатора длины.

Спецификатор длины имеет длину два байта, и он имеет порядковый номер. Итак, что вы будете делать, это искать FF, и если следующий байт не равен 0x00, 0x01 или 0xD0-0xD8, вы читаете спецификатор длины и пропускаете вперед в потоке, пока спецификатор длины говорит минус два байта.

Кроме того, каждый маркер может быть дополнен в начале любым количеством FF.

Когда вы попадаете в FFD9, вы находитесь в конце потока.

Конечно, вы можете читать поток слово в слово, ища FF, если вы хотите производительность, но это оставлено в качестве упражнения для читателя. ; -)

16 голосов
/ 03 января 2011

Быстрый просмотр статьи в Википедии в формате JPEG дал бы вам ответ:

  • байтов 0xFF, 0xD8 указывают начало изображения
  • байтов 0xFF, 0xD9 указывают на конец изображения
1 голос
/ 26 января 2018

Если вы отправляете изображения через байтовый массив, вы можете просто добавить размер файла изображения в виде пары байтов до начала файла.
Клиент захватывает первые два байта, чтобы найти указанное число байтов (мы назовем это x), и отбрасывает их, затем закачивает следующее число x байтов в буфер, который он может записать в файл.
Промойте и повторите для всех следующих JPEG.

Альтернативой является просто поиск маркера FFD9 - если я не ошибаюсь, любое сжатое значение FF будет закодировано как FF00 (байт 00 сбрасывается, а байт FF сохраняется).
Проблема в том, что вы получаете такие вещи, как миниатюры с их собственными заголовками FFD9, но они содержатся внутри сегмента в заголовках. Эти сегменты имеют значение длины в двух байтах после маркера, так что вы можете просто пропустить до конца любого сегмента, с которым вы столкнетесь, чтобы избежать преждевременного обнаружения eoi.

...