将Exif数据写回到GD图库旋转的图像中

问题描述 投票:0回答:1

当尝试通过 GD 图像旋转图像后将原始 exif 数据附加回图像时,我遇到了麻烦。

如何旋转图像

rotatedImage = gdImageRotateInterpolated(image, (360-rotationDeg)%360, 0);
imgBuffer = (unsigned char *)gdImageJpegPtr(rotatedImage, &imgSize, 85);

然后我有一个函数尝试通过将图像缓冲区与 exif 缓冲区相结合来将从原始图像中提取的 exif 数据写入旋转的图像,但在检查图像时我仍然看不到 Exif 数据。我正在使用

libexif

writeExifData(unsigned char* &imageBuffer, int &size, ExifData* exifData) {
    if (!exifData) {
        return;
    }
    TRACE("Image Size: %d", size);
    // save exif data into buffer
    unsigned char* buf = NULL;
    unsigned int bufSize = 0;
    exif_data_save_data(exifData, &buf, &bufSize);
    std::vector<unsigned char> combinedBuffer(size + bufSize);

    // Copy the image buffer
    std::copy(imageBuffer, imageBuffer + size, combinedBuffer.begin());

    // Copy the EXIF buffer
    std::copy(buf, buf + bufSize, combinedBuffer.begin() + size);

    unsigned char* newImageBuffer = (unsigned char*)malloc(combinedBuffer.size());

    memcpy(newImageBuffer, combinedBuffer.data(), combinedBuffer.size());
    imageBuffer = newImageBuffer;
    size = combinedBuffer.size();
}

还有其他方法可以让新图像缓冲区包含原始图像中的所有 Exif 数据吗?

c++ gd libexif
1个回答
0
投票

JPEG 图像格式 由许多使用标签长度值编码的片段组成。此外,EXIF 的 APP1 数据应该紧接在文件中的 SOI 标记之后,即 JPEG 的前两个字节。

exif_save_data
产生“值”部分,但您需要自己将其包装在一个段中。

因此,您可以执行以下操作:

struct jpeg_header {
  uint16_t soi;
  uint16_t app1;
  uint16_t exif_len;
} jh = { htobe16(0xFFD8), htobe16(0xFFE1), htobe16(2 + bufSize) };

unsigned char* newImageBuffer = (unsigned char*)malloc(sizeof(jh) + size - 2 /* duplicate SOI */);
unsigned char* write = newImageBuffer;
write = std::copy(reinterpret_cast<unsigned char *>(&jh), reinterpret_cast<unsigned char *>(&jh) + sizeof(jh), write);
write = std::copy(buf, buf+bufSize, write);
write = std::copy(imageBuffer+2, imageBuffer+size, write);

return newImageBuffer;

如果您无法访问

htobe16
,您也可以使用
htons

© www.soinside.com 2019 - 2024. All rights reserved.