Сжатие растрового изображения в памяти с помощью C++

У меня есть программа, которая захватывает изображение с помощью BitBlt() и сохраняет его в переменной unsigned char* image. В идеале, прежде чем загружать его на свой сервер, я хотел бы сжать его, так как он довольно большой в несжатом виде. Я пробовал несколько разных способов с zlib, писал свой собственный метод кодирования длин серий и многое другое, но безуспешно. Я списываю это на то, что у меня нет сильного понимания сжатия.

Я искал и нашел несколько примеров с использованием zlib, но мое изображение остается того же размера после попытки его сжатия. Вот этот код:

unsigned char* compressBitmap(size_t inImgSize, unsigned char* inImage)
{
    uLongf srcLen = inImgSize;
    uLongf destLen = compressBound(srcLen);
    unsigned char* outImage = new unsigned char[destLen];

    int res = compress((Bytef*)outImage, &destLen, (Bytef*)inImage, srcLen);
    return outImage;
}

Я проверил и подтвердил, что он не возвращает ошибку. Все выполняется, и образ прекрасно доходит до сервера, просто не сжимается вообще. Я, вероятно, делаю кучу глупых ошибок, поэтому любая помощь приветствуется.


person LJR135    schedule 07.11.2019    source источник
comment
Кажется, вы вводите destLen и просто возвращаете простой указатель на буфер без соответствующего размера. После завершения compress он сохраняет фактический размер сжатых данных в буфере (вероятно, меньший, чем наихудший случай, заданный compressBound). | Учитывая, что вы работаете на C++, было бы неплохо использовать что-то вроде std::vector вместо необработанных массивов.   -  person Dan Mašek    schedule 07.11.2019
comment
Кроме того, ZLib является разумным выбором (в конце концов, на этом основан PNG), но, поскольку вы имеете дело с изображением, вы можете использовать кодек изображения напрямую, а не пытаться изобретать велосипед.   -  person Dan Mašek    schedule 07.11.2019


Ответы (1)


Сжатие без потерь данных изображения обычно не позволяет уменьшить размер файла (особенно фотографии, возможно, простые значки). Если вы хотите узнать, действительно ли работает сжатие, попробуйте загрузить полностью черное изображение и посмотрите, уменьшится ли размер. Если вы видите уменьшение размера файла на черном изображении, но не на изображениях, которые вы используете, возможно, вам придется рассмотреть возможность использования вместо этого формата с потерями (например, jpeg, png и т. д.).

person robthebloke    schedule 07.11.2019
comment
Спасибо за ответ. Я попробовал полностью черное изображение, но того же размера. Я согласен с использованием одного из этих других форматов. Моя проблема заключалась в том, что я не мог найти библиотеку или способ сохранить все это в памяти. Такие библиотеки, как boost, похоже, хотят записывать и/или читать файл. Есть ли у вас рекомендации по его преобразованию, но непосредственному размещению в памяти? - person LJR135; 07.11.2019
comment
PNG — это кодек изображений без потерь. Сжимает с помощью ZLib. Есть много других, которые либо полностью без потерь, либо поддерживают этот режим. - person Dan Mašek; 07.11.2019