使用Javascript从JPEG中提取IPTC信息

时间:2022-02-06 21:21:28

I'm trying to extract IPTC photo caption information from a JPEG file using Javascript. (I know I can do this server-side, but I'm looking specifically for a Javascript solution.)

我正在尝试使用Javascript从JPEG文件中提取IPTC照片标题信息。(我知道我可以在服务器端执行此操作,但我正在寻找专门的Javascript解决方案。)

I found this script, which extracts EXIF information ... but I'm not sure how to adapt it to grab IPTC data.

我找到了这个脚本,它提取了EXIF信息……但我不确定如何利用它来获取IPTC数据。

Are there any existing scripts that offer such functionality? If not, how would you modify the EXIF script to also parse IPTC data?

是否有任何现有的脚本提供这样的功能?如果没有,如何修改EXIF脚本以解析IPTC数据?

UPDATE

更新

I've modified the EXIF script I linked above. It sorta does what I want, but it's not grabbing the right data 100 percent of the time.

我已经修改了上面链接的EXIF脚本。它可以做我想做的事,但是它不能百分之百地获取正确的数据。

After line 401, I added:

在第401行之后,我补充说:

else if (iMarker == 237) {
        // 0xED = Application-specific 13 (Photoshop IPTC)                
        if (bDebug) log("Found 0xFFED marker");   
        return readIPTCData(oFile, iOffset + 4, getShortAt(oFile, iOffset+2, true)-2);                       
}

And then elsewhere in the script, I added this function:

然后在脚本的其他地方,我添加了这个函数:

function readIPTCData(oFile, iStart, iLength) {
    exif = new Array();

if (getStringAt(oFile, iStart, 9) != "Photoshop") {
    if (bDebug) log("Not valid Photoshop data! " + getStringAt(oFile, iStart, 9));
    return false;
}

var output = '';
var count = 0;
two = new Array();
for (i=0; i<iLength; i++) {
   if (getByteAt(oFile, iStart + i) == 2 && getByteAt(oFile, iStart + i + 1) == 120) {
      var caption = getString2At(oFile, iStart + i + 2, 800);
   }
   if (getByteAt(oFile, iStart + i) == 2 && getByteAt(oFile, iStart + i + 1) == 80) {
      var credit = getString2At(oFile, iStart + i + 2, 300);
   }       
}

exif['ImageDescription'] = caption;
exif['Artist'] = credit;

return exif;

}

So let me now modify my question slightly. How can the function above be improved?

现在我稍微修改一下我的问题。如何改进上述功能?

2 个解决方案

#1


6  

For what it's worth, I extrapolated on this a bit... I haven't done a whole lot of testing, but the few test images I have seem to work.

就其价值而言,我对此做了一些推断……我还没有做过很多测试,但是我所做的少数几个测试图像似乎是有效的。

    var bDebug = false;

    var fieldMap = {
        120 : 'caption',
        110 : 'credit',
        25 : 'keywords',
        85 : 'byline',
        122 : 'captionWriter',
        105 : 'headline',
        116 : 'copyright',
        15 : 'category'
    };

    function readIPTCData(oFile, iStart, iLength) {
        var data = {};

        if (oFile.getStringAt(iStart, 9) != "Photoshop") {
            if (bDebug) log("Not valid Photoshop data! " + oFile.getStringAt(iStart, 9));
            return false;
        }

        var fileLength = oFile.getLength();

        var length, offset, fieldStart, title, value;
        var FILE_SEPARATOR_CHAR = 28,
            START_OF_TEXT_CHAR = 2;

        for (var i = 0; i < iLength; i++) {

            fieldStart = iStart + i;
            if(oFile.getByteAt(fieldStart) == START_OF_TEXT_CHAR && oFile.getByteAt(fieldStart + 1) in fieldMap) {
                length = 0;
                offset = 2;

                while(
                    fieldStart + offset < fileLength &&
                    oFile.getByteAt(fieldStart + offset) != FILE_SEPARATOR_CHAR &&
                    oFile.getByteAt(fieldStart + offset + 1) != START_OF_TEXT_CHAR) { offset++; length++; }

                if(!length) { continue; }

                title = fieldMap[oFile.getByteAt(fieldStart + 1)];
                value = oFile.getStringAt(iStart + i + 2, length) || '';
                value = value.replace('\000','').trim();

                data[title] = value;
                i+=length-1;
            }
        }

        return data;

    }

    function findIPTCinJPEG(oFile) {
        var aMarkers = [];

        if (oFile.getByteAt(0) != 0xFF || oFile.getByteAt(1) != 0xD8) {
            return false; // not a valid jpeg
        }

        var iOffset = 2;
        var iLength = oFile.getLength();
        while (iOffset < iLength) {
            if (oFile.getByteAt(iOffset) != 0xFF) {
                if (bDebug) console.log("Not a valid marker at offset " + iOffset + ", found: " + oFile.getByteAt(iOffset));
                return false; // not a valid marker, something is wrong
            }

            var iMarker = oFile.getByteAt(iOffset+1);

            if (iMarker == 237) {
                if (bDebug) console.log("Found 0xFFED marker");
                return readIPTCData(oFile, iOffset + 4, oFile.getShortAt(iOffset+2, true)-2);

            } else {
                iOffset += 2 + oFile.getShortAt(iOffset+2, true);
            }

        }

    }

    IPTC.readFromBinaryFile = function(oFile) {
        return findIPTCinJPEG(oFile);
    }

#2


0  

Well, this should get you going on creating your own javascript parser if you can't find a library that already does this.

如果你找不到一个已经这样做的库,这将使你继续创建自己的javascript解析器。

http://www.iptc.org/std/photometadata/specification/IPTC-PhotoMetadata%28200907%29_1.pdf

http://www.iptc.org/std/photometadata/specification/IPTC-PhotoMetadata%28200907%29_1.pdf

#1


6  

For what it's worth, I extrapolated on this a bit... I haven't done a whole lot of testing, but the few test images I have seem to work.

就其价值而言,我对此做了一些推断……我还没有做过很多测试,但是我所做的少数几个测试图像似乎是有效的。

    var bDebug = false;

    var fieldMap = {
        120 : 'caption',
        110 : 'credit',
        25 : 'keywords',
        85 : 'byline',
        122 : 'captionWriter',
        105 : 'headline',
        116 : 'copyright',
        15 : 'category'
    };

    function readIPTCData(oFile, iStart, iLength) {
        var data = {};

        if (oFile.getStringAt(iStart, 9) != "Photoshop") {
            if (bDebug) log("Not valid Photoshop data! " + oFile.getStringAt(iStart, 9));
            return false;
        }

        var fileLength = oFile.getLength();

        var length, offset, fieldStart, title, value;
        var FILE_SEPARATOR_CHAR = 28,
            START_OF_TEXT_CHAR = 2;

        for (var i = 0; i < iLength; i++) {

            fieldStart = iStart + i;
            if(oFile.getByteAt(fieldStart) == START_OF_TEXT_CHAR && oFile.getByteAt(fieldStart + 1) in fieldMap) {
                length = 0;
                offset = 2;

                while(
                    fieldStart + offset < fileLength &&
                    oFile.getByteAt(fieldStart + offset) != FILE_SEPARATOR_CHAR &&
                    oFile.getByteAt(fieldStart + offset + 1) != START_OF_TEXT_CHAR) { offset++; length++; }

                if(!length) { continue; }

                title = fieldMap[oFile.getByteAt(fieldStart + 1)];
                value = oFile.getStringAt(iStart + i + 2, length) || '';
                value = value.replace('\000','').trim();

                data[title] = value;
                i+=length-1;
            }
        }

        return data;

    }

    function findIPTCinJPEG(oFile) {
        var aMarkers = [];

        if (oFile.getByteAt(0) != 0xFF || oFile.getByteAt(1) != 0xD8) {
            return false; // not a valid jpeg
        }

        var iOffset = 2;
        var iLength = oFile.getLength();
        while (iOffset < iLength) {
            if (oFile.getByteAt(iOffset) != 0xFF) {
                if (bDebug) console.log("Not a valid marker at offset " + iOffset + ", found: " + oFile.getByteAt(iOffset));
                return false; // not a valid marker, something is wrong
            }

            var iMarker = oFile.getByteAt(iOffset+1);

            if (iMarker == 237) {
                if (bDebug) console.log("Found 0xFFED marker");
                return readIPTCData(oFile, iOffset + 4, oFile.getShortAt(iOffset+2, true)-2);

            } else {
                iOffset += 2 + oFile.getShortAt(iOffset+2, true);
            }

        }

    }

    IPTC.readFromBinaryFile = function(oFile) {
        return findIPTCinJPEG(oFile);
    }

#2


0  

Well, this should get you going on creating your own javascript parser if you can't find a library that already does this.

如果你找不到一个已经这样做的库,这将使你继续创建自己的javascript解析器。

http://www.iptc.org/std/photometadata/specification/IPTC-PhotoMetadata%28200907%29_1.pdf

http://www.iptc.org/std/photometadata/specification/IPTC-PhotoMetadata%28200907%29_1.pdf