Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 没有所有编解码器信息的jpeg文件有多大?_Python_C++_Compression_Jpeg - Fatal编程技术网

Python 没有所有编解码器信息的jpeg文件有多大?

Python 没有所有编解码器信息的jpeg文件有多大?,python,c++,compression,jpeg,Python,C++,Compression,Jpeg,我想知道如果没有jpeg的元数据、头和编解码器信息,jpeg文件有多大。因此,最后您将只检索压缩的像素数据,我认为它由DCT系数、量化和哈夫曼表组成 但是如何使用Python或C/C++提取这些数组的大小呢 我确实尝试使用libjpeg,但没有找到计算压缩数据大小的方法 元数据的数量完全取决于编码器。JPEG流中唯一需要的头是2字节SOI标记。唯一的页脚是2字节EOI标记 其他任何东西都是编码器放入的东西。这里有一段代码,大致完成了要求的内容。我认为任何图书馆都没有现成的解决方案 它不是非常整洁

我想知道如果没有jpeg的元数据、头和编解码器信息,jpeg文件有多大。因此,最后您将只检索压缩的像素数据,我认为它由DCT系数、量化和哈夫曼表组成

但是如何使用Python或C/C++提取这些数组的大小呢


我确实尝试使用libjpeg,但没有找到计算压缩数据大小的方法

元数据的数量完全取决于编码器。JPEG流中唯一需要的头是2字节SOI标记。唯一的页脚是2字节EOI标记


其他任何东西都是编码器放入的东西。

这里有一段代码,大致完成了要求的内容。我认为任何图书馆都没有现成的解决方案

它不是非常整洁,也不像我希望的那么简单。我已经从我的~/Pictures文件夹和其他地方运行了几百个随机图像,但不能保证它能处理任何图像-我认为我所有的图像都是由两个不同的应用程序创建的。其他一些可能不会,但同样,不同的生产者可能会使用不同的字段,或者以这种代码无法处理的形式生成数据。如果它坏了,你可以保留所有的碎片,但不退款

我将留给读者来决定什么是实际的图像数据,什么不是。请注意,块大小不包括块头本身,即顶部的另2个字节

噢,是的,这是C++和C的混合体。我只是把这些代码和我为不同目的而准备的部分代码结合在一起,整理起来,这样就不是一个烂摊子,但是这绝不是我最好的编码…… 我也在这里添加了代码:


我非常肯定libjpeg[我刚才通读了文档]不会在不更改源代码的情况下直接向您提供这些信息。因为Python的JPEG代码是基于libjpeg的,所以我怀疑它是否会有帮助。很明显,您可以编写代码来读取头等等,然后从总大小中减去元数据大小?没有元数据,其余的都没用了。我相信JPEG文件的开头大约有9字节的纯标识数据。解码还需要其他一切。@JohnAnderson:有许多可选字段允许文件制作人添加额外的元数据,例如相机的曝光设置[以及哪个型号、镜头焦距、是否使用闪光灯等]、用户复制权信息、照片编辑器数据和许多其他内容。这类信息绝对不是解码实际图像内容所需信息的一部分。因此,虽然最小的JPEG可能会非常低的开销,但这并不意味着在某些情况下无法添加大量信息。@JesperJuhl我想将JPEG与利用生成性对抗网络的压缩方法进行比较,该方法只输出单个向量作为压缩数据。因为我将只处理64x64x3图像,与神经网络方法相比,编解码器信息的开销对压缩率有着有意义的影响。在实践中,编码器增加了合理的数量。我开始编写一个程序,从头字段中读取JPEG文件中的内容,但这比仅读取标记和长度要复杂一些。然而,据我目前所知,我的4.1K数据文件中有大约3160字节的元数据——这是来自GIMP的。同一个压缩设置较低的输入文件,图片中的更多细节似乎都有相同的3160字节元数据。这是哪一个?还是你自己做的?我假设Baudcode想知道它是多少,因为没有一个编码器不是自制的,没有已知的开销。顺便说一句,在测试我的代码时,我浏览了数百个图像,虽然我没有检查每个图像,但似乎每个图像至少都存储了一些APP1或COM数据。在某些情况下,我怀疑这是预览图像,但我根本没有尝试分析内容。不幸的是,它只适用于某些图像。像这样的一些失败了:。顺便说一句,这不起作用,你到底是什么意思?我下载了这些图片,它们都带着一些输出通过了程序——我没有对它应该是什么和它是什么投入任何精力,但是输出看起来总体上是正常的。当然,这可能是因为图像与您上传的图像并不完全相同。许多网站在上传过程中会对其图像重新编码,主要是为了减小尺寸,因此您可能需要首先检查从链接下载的图像是否存在再现问题。然后更详细地描述出哪里出了问题。对不起,这是我代码中的一个bug:一切都是完美的。
#include <fstream>
#include <ios>
#include <vector>
#include <cstdint>


#define die(str, ...) \
    do { printf(str, __VA_ARGS__); exit(1); } while(0)

void read_bytes(std::ifstream &f, uint8_t *buffer, std::streamsize sz)
{
    if(!f.read(reinterpret_cast<char*>(buffer), sz))
    {
        die("Expected to read %zd bytes\n", sz);
    }
}

uint32_t read_size(std::ifstream &f)
{
    uint8_t buffer[2];
    read_bytes(f, buffer, 2);
    uint32_t size = buffer[0] << 8 | buffer[1];
    return size;
}

void skip_size(std::ifstream &f, std::streamsize to_skip)
{
    f.seekg(to_skip - 2, std::ios_base::cur);
}

void check_buffer(uint8_t *buffer, const std::vector<uint8_t> &val)
{
    uint8_t *b = buffer;
    for(auto v : val)
    {
        if (*b != v)
        {
            die("Mismatch! Expected %02x, got %02x\n", v, *b);
        }
        b++;
    }
}

uint32_t find_next_header(std::ifstream &f)
{
    uint8_t b;
    bool found = false;
    uint32_t count = 0;
    do
    {
        read_bytes(f, &b, 1);
        if (b == 0xFF)
        {
            if (f.peek() == 0x00)
            {
                read_bytes(f, &b, 1);
                count+= 2;
            }
            else
            {
                f.unget();
                found = true;
            }
        }
        else
        {
            count++;
        }
    } while(!found);

    return count;
}

int main(int argc, char **argv)
{
    if (argc != 2)
    {
        printf("Expected filename as argument\n");
        exit(1);
    }

    std::ifstream f(argv[1], std::ios_base::in|std::ios_base::binary);
    if (!f)
    {
        die("Couldn't open the file %s\n", argv[1]);
    }

    uint8_t buffer[2];
    uint32_t total = 0;

    read_bytes(f, buffer, 2);
    check_buffer(buffer, {0xFF, 0xd8});
    total += 2;

    bool eoi = false;
    do
    {
        uint32_t size;
        read_bytes(f, buffer, 2);
        if (buffer[0] != 0xff)
        {
            die("Expected 0xFF byte, got %02x at offset %zu\n", 
                buffer[0], (size_t)f.tellg());
        }
        total += 2;
        switch(buffer[1])
        {
        case 0xE0:
        case 0xE1:
        case 0xE2:
        case 0xE3:
        case 0xE4:
        case 0xE5:
        case 0xE6:
        case 0xE7:
        case 0xE8:
        case 0xE9:
        case 0xEA:
        case 0xEB:
        case 0xEC:
        case 0xED:
        case 0xEE:
        case 0xEF:
            size = read_size(f);
            total += size;
            printf("APP Data Type %02x: %u bytes of application data\n",
                   buffer[1], size);
            skip_size(f, size);
            break;

        case 0xDB:
            size = read_size(f);
            total += size;
            printf("DQT: %u bytes of quantization data\n", size);
            skip_size(f, size);
            break;

        case 0xC0:
        case 0xC2:
            size = read_size(f);
            total += size;
            printf("SOF: %u bytes of frame data\n", size);
            skip_size(f, size);
            break;

        case 0xC4:
            size = read_size(f);
            total += size;
            printf("DHT: %u bytes of huffman tables\n", size);
            skip_size(f, size);
            break;

        case 0xDA:
            size = read_size(f);
            skip_size(f, size);
            size += find_next_header(f);
            total += size;
            printf("SOS: %u bytes of scan data\n", size);
            break;

        case 0xD9:
            printf("EOI: end of image\n");
            eoi = true;
            break;

        case 0xFE:
            size = read_size(f);
            skip_size(f, size);
            total += size;
            printf("COM: comment %u bytes\n", size);
            break;

        default:
            die("Expected known encoding byte, got %02x\n", buffer[1]);
            break;
        }
    } while(!eoi);
    printf("Total size = %u\n", total);
}