예제 #1
0
// convert from KisMetaData value to ExifVersion and FlashpixVersion
Exiv2::Value* kmdValueToExifVersion(const KisMetaData::Value& value)
{
    Exiv2::DataValue* dvalue = new Exiv2::DataValue;
    QString ver = value.asVariant().toString();
    dvalue->read((const Exiv2::byte*)ver.toLatin1().constData(), ver.size());
    return dvalue;
}
예제 #2
0
bool KExiv2::setImagePreview(const QImage& preview, bool setProgramName) const
{
    if (!setProgramId(setProgramName))
        return false;

    if (preview.isNull())
    {
        removeIptcTag("Iptc.Application2.Preview");
        removeIptcTag("Iptc.Application2.PreviewFormat");
        removeIptcTag("Iptc.Application2.PreviewVersion");
        return true;
    }

    try
    {
        QByteArray data;
        QBuffer buffer(&data);
        buffer.open(QIODevice::WriteOnly);

        // A little bit compressed preview jpeg image to limit IPTC size.
        preview.save(&buffer, "JPEG");
        kDebug() << "JPEG image preview size: (" << preview.width() << " x "
                 << preview.height() << ") pixels - " << data.size() << " bytes";

        Exiv2::DataValue val;
        val.read((Exiv2::byte *)data.data(), data.size());
        d->iptcMetadata()["Iptc.Application2.Preview"] = val;

        // See http://www.iptc.org/std/IIM/4.1/specification/IIMV4.1.pdf Appendix A for details.
        d->iptcMetadata()["Iptc.Application2.PreviewFormat"]  = 11;  // JPEG
        d->iptcMetadata()["Iptc.Application2.PreviewVersion"] = 1;

        return true;
    }
    catch( Exiv2::Error& e )
    {
        d->printExiv2ExceptionError("Cannot get image preview using Exiv2 ", e);
    }
    catch(...)
    {
        kError() << "Default exception from Exiv2";
    }

    return false;
}
예제 #3
0
int main(int argc, char* const argv[])
try {
    if (argc != 3) {
        std::cout << "Usage: " << argv[0] << " image datafile\n";
        return 1;
    }
    std::string file(argv[1]);
    std::string data(argv[2]);

    // Read data file into data buffer
    Exiv2::FileIo io(data);
    if (io.open() != 0) {
      throw Exiv2::Error(Exiv2::kerDataSourceOpenFailed, io.path(), Exiv2::strError());
    }
    Exiv2::DataBuf buf((long)io.size());
    std::cout << "Reading " << buf.size_ << " bytes from " << data << "\n";
    io.read(buf.pData_, buf.size_);
    if (io.error() || !io.eof()) throw Exiv2::Error(Exiv2::kerFailedToReadImageData);

    // Read metadata from file
    Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(file);
    assert(image.get() != 0);
    image->readMetadata();

    // Set Preview field to the content of the data file
    Exiv2::DataValue value;
    value.read(buf.pData_, buf.size_);
    Exiv2::IptcData& iptcData = image->iptcData();
    std::cout << "IPTC fields: " << iptcData.size() << "\n";
    iptcData["Iptc.Application2.Preview"] = value;
    std::cout << "IPTC fields: " << iptcData.size() << "\n";

    // Set IRB, compare with IPTC raw data
    Exiv2::DataBuf irb = Exiv2::Photoshop::setIptcIrb(0, 0, iptcData);
    std::cout << "IRB buffer : " << irb.size_ << "\n";
    const Exiv2::byte* record;
    uint32_t sizeHdr;
    uint32_t sizeData;
    Exiv2::Photoshop::locateIptcIrb(irb.pData_, irb.size_, &record, &sizeHdr, &sizeData);
    Exiv2::DataBuf rawIptc = Exiv2::IptcParser::encode(iptcData);
    std::cout << "Comparing IPTC and IRB size... ";
    if (static_cast<uint32_t>(rawIptc.size_) != sizeData) {
        std::cout << "not ";
    }
    std::cout << "ok\n";

    std::cout << "Comparing IPTC and IRB data... ";
    if (0 != memcmp(rawIptc.pData_, record + sizeHdr, sizeData)) {
        std::cout << "not ";
    }
    std::cout << "ok\n";

    // Set Iptc data and write it to the file
    image->writeMetadata();

    return 0;
}
catch (Exiv2::AnyError& e) {
    std::cout << "Caught Exiv2 exception '" << e << "'\n";
    return -1;
}
예제 #4
0
// *****************************************************************************
// Main
int main(int argc, char* const argv[])
try {

    if (argc != 2) {
        std::cout << "Usage: " << argv[0] << " file\n";
        return 1;
    }

    Exiv2::ExifData exifData;
    int rc = exifData.read(argv[1]);
    if (rc) {
        std::string error = Exiv2::ExifData::strError(rc, argv[1]);
        throw Exiv2::Error(error);
    }

    /*
      There are two pitfalls that we need to consider when setting the Exif user
      comment (Exif.Photo.UserComment) of an image:

      First, the type of the Exif user comment tag is "undefined" (and not
      ASCII) according to the Exif standard. This means that in Exiv2, we have
      to deal with a DataValue (and not an AsciiValue). DataValue has the usual
      two read methods, however, the one taking a const std::string& buf expects
      the string to contain a series of integers (e.g., "0 1 2") and not a text
      string. Thus, we need to use the read function that reads the value from a
      character buffer of a given length.

      Second, the Exif comment field starts with an eight character area that
      identifies the used character set. For ASCII, these eight characters are
      "ASCII\0\0\0". The actual comment follows after this code.

      Note: There is a more simple Exif tag for the title of an image. It is a
      20 byte string (type ASCII) and does not store two-byte characters.
      (Image.OtherTags.ImageDescription)
     */

    // Initialise a data value with the character set and comment
    std::string charset("ASCII\0\0\0", 8);
    std::string comment("A comment added to the Exif metadata through Exiv2");
    Exiv2::DataValue value;
    value.read(reinterpret_cast<const Exiv2::byte*>((charset + comment).data()), 
                8 + static_cast<long>(comment.size()));

    // Set the Exif comment
    Exiv2::ExifKey key("Exif.Photo.UserComment");
    Exiv2::ExifData::iterator pos = exifData.findKey(key);
    if (pos != exifData.end()) {
        // Use the existing Exif UserComment metadatum if there is one
        pos->setValue(&value);
    }
    else {
        // Otherwise add a new UserComment metadatum
        exifData.add(key, &value);
        pos = exifData.findKey(key);
    }

    // Now we should have a valid iterator in any case. We use the metadatum
    // output operator to print the formatted value
    std::cout << "Writing user comment '" << *pos << "' back to the image\n";

    rc = exifData.write(argv[1]);
    if (rc) {
        std::string error = Exiv2::ExifData::strError(rc, argv[1]);
        throw Exiv2::Error(error);
    }

   return rc;
}
catch (Exiv2::Error& e) {
    std::cout << "Caught Exiv2 exception '" << e << "'\n";
    return -1;
}