Запись растрового изображения в строку, вставленную из FILE * или XImage в PNG - PullRequest
2 голосов
/ 16 декабря 2010

Я преобразовал вывод XImage моего кода в Bitmap, но выходной файл большой, поэтому я подумал о сжатии его с помощью lzrw я использую этот код для записи растрового изображения в файл

fwrite(&bmpFileHeader, sizeof(bmpFileHeader), 1, fp);
fwrite(&bmpInfoHeader, sizeof(bmpInfoHeader), 1, fp);
fwrite(pImage->data, 4*pImage->width*pImage->height, 1, fp);

есть ли в любом случае, я мог бы записать его в (char *) insted из (FILE *), чтобы я мог использовать сжатие lzrw на нем? или, что еще лучше, каким-то образом преобразовать XImage в PNG напрямую ...

спасибо;

Ответы [ 2 ]

1 голос
/ 16 декабря 2010

Используйте memcpy вместо fwrite

char* tmp = buf;
memcpy(tmp, &bmpFileHeader, sizeof(bmpFileHeader));
tmp += sizeof(bmpFileHeader);
memcpy(tmp, &bmpInfoHeader, sizeof(bmpInfoHeader));
tmp += sizeof(bmpInfoHeader);
memcpy(tmp, pImage->data, 4*pImage->width*pImage->height);

РЕДАКТИРОВАТЬ: я обновляю код, спасибо @bdk за указание

0 голосов
/ 16 декабря 2010

Для копии в памяти, используйте memcpy, как говорит DReJ, но если вы хотите сохранить изображение в формате PNG, вы можете сделать хуже, чем смотреть на простую простую библиотеку PNG, такую ​​как LodePNG:

http://members.gamedev.net/lode/projects/LodePNG/

Я бы не стал тратить время на перекомпоновку стороны сжатия, если бы была простая альтернатива - есть более важные проблемы, над которыми вы можете работать.


РЕДАКТИРОВАТЬ - мой код для сохранения PNG с использованием LodePNG стоит того:

void PNGSaver::save_image24(const std::string& filename, const Image24_CPtr& image)
{
    std::vector<unsigned char> buffer;
    encode_png(image, buffer);
    LodePNG::saveFile(buffer, filename);
}

void PNGSaver::encode_png(const Image24_CPtr& image, std::vector<unsigned char>& buffer)
{
    int width = image->width();
    int height = image->height();
    const int pixelCount = width*height;

    // Construct the image data array.
    std::vector<unsigned char> data(pixelCount*4);
    unsigned char *p = &data[0];
    for(int y=0; y<height; ++y)
        for(int x=0; x<width; ++x)
        {
            Pixel24 pixel = (*image)(x,y);
            *p      = pixel.r();
            *(p+1)  = pixel.g();
            *(p+2)  = pixel.b();
            *(p+3)  = 255;
            p += 4;
        }

    // Encode the PNG.
    LodePNG::encode(buffer, &data[0], width, height);
}
...