Получение размера изображения JPEG из его двоичного файла - PullRequest
8 голосов
/ 25 марта 2010

У меня много файлов JPEG с различным размером изображения. Например, вот первые 640 байтов, заданные hexdump изображения размером 256 * 384 (пикселей):

0000000: ffd8 ffe0 0010 4a46 4946 0001 0101 0048  ......JFIF.....H
0000010: 0048 0000 ffdb 0043 0003 0202 0302 0203  .H.....C........
0000020: 0303 0304 0303 0405 0805 0504 0405 0a07  ................
0000030: 0706 080c 0a0c 0c0b 0a0b 0b0d 0e12 100d  ................

Я думаю, информация о размере должна быть в этих строках. Но я не могу увидеть, какие байты дают размеры правильно. Может кто-нибудь помочь мне найти поля, которые содержат информацию о размере?

Ответы [ 3 ]

10 голосов
/ 25 марта 2010

В соответствии с разделом Синтаксис и структура на странице JPEG в Википедии ширина и высота изображения не сохраняются в самом изображении - или По крайней мере, не так легко найти.


Тем не менее, цитата из FAQ по сжатию изображений JPEG, часть 1/2 :

Тема: [22] Как моя программа может извлечь размеры изображения из JPEG файл

Заголовок файла JPEG состоит из серия блоков, называемых «маркерами». Высота и ширина изображения сохраняются в маркер типа СОФн (Старт Оф Рамка, тип N) .
Чтобы найти SOFn Вы должны пропустить предыдущее маркеры; вам не нужно знать, что в других типах маркеров, просто используйте их длинные слова, чтобы пропустить их.
Минимальная необходимая логика возможно, страница кода C.
(Некоторые люди рекомендовали просто искать для пары байтов, представляющих SOFn, не обращая внимания на маркер блочная структура. Это небезопасно потому что предыдущий маркер может содержать шаблон SOFn, случайно или потому что он содержит JPEG-сжатый уменьшенное изображение. Если вы не будете следовать структура маркера, которую вы получите размер эскиза вместо основной размер изображения.)
Обильно прокомментированный пример в C можно найти в rdjpgcom.c в дистрибутиве IJG (см. часть 2, пункт 15).
код Perl можно найти в wwwis, из http://www.tardis.ed.ac.uk/~ark/wwwis/.

(Э-э, эта ссылка кажется неработоспособной ...)


Вот часть кода C, которая может вам помочь: Декодирование ширины и высоты файла JPEG (JFIF)

2 голосов
/ 28 января 2018

Эта функция будет читать свойства JPEG

function jpegProps(data) {          // data is an array of bytes
    var off = 0;
    while(off<data.length) {
        while(data[off]==0xff) off++;
        var mrkr = data[off];  off++;

        if(mrkr==0xd8) continue;    // SOI
        if(mrkr==0xd9) break;       // EOI
        if(0xd0<=mrkr && mrkr<=0xd7) continue;
        if(mrkr==0x01) continue;    // TEM

        var len = (data[off]<<8) | data[off+1];  off+=2;  

        if(mrkr==0xc0) return {
            bpc : data[off],     // precission (bits per channel)
            w   : (data[off+1]<<8) | data[off+2],
            h   : (data[off+3]<<8) | data[off+4],
            cps : data[off+5]    // number of color components
        }
        off+=len-2;
    }
}
0 голосов
/ 22 января 2019

Если вы работаете в системе Linux и имеете PHP под рукой, варианты этого php-скрипта могут привести к тому, что вы ищете:

#! /usr/bin/php -q
<?php

if (file_exists($argv[1]) ) {

    $targetfile = $argv[1];

    // get info on uploaded file residing in the /var/tmp directory:
    $safefile       = escapeshellcmd($targetfile);
    $getinfo        = `/usr/bin/identify $safefile`;
    $imginfo        = preg_split("/\s+/",$getinfo);
    $ftype          = strtolower($imginfo[1]);
    $fsize          = $imginfo[2];

    switch($fsize) {
        case 0:
            print "FAILED\n";
            break;
        default:
            print $safefile.'|'.$ftype.'|'.$fsize."|\n";
    }
}

// eof

host> imageinfo 009140_DJI_0007.JPG

009140_DJI_0007.JPG | JPEG | 4000x3000 |

(выводит имя файла, тип файла, размеры файла в формате с разделителями-пробирками)

со страницы руководства:

Для получения дополнительной информации о команде «identifier» укажите в браузере [...] http://www.imagemagick.org/script/identify.php.

...