在一个测试用例中使用纯 JS 检索图像方向失败
Using pure JS to retrieve image orientation failing in one test case
我是一名服务器端开发人员,最近正在学习纯 JS 的技巧。我正在研究的一个实际例子是图像处理。这个问题是关于我努力检索图像方向信息以便随后旋转 and/or 反映它。
这个优秀的 SO answer 让我开始了。我写的代码是:
// used to determine orientation information
function get_orientation(file, callback) {
var reader = new FileReader();
reader.onload = function(e) {
var view = new DataView(e.target.result);
if (view.getUint16(0, false) != 0xFFD8) return callback(-2);
var length = view.byteLength, offset = 2;
while (offset < length) {
var marker = view.getUint16(offset, false);
offset += 2;
if (marker == 0xFFE1) {
if (view.getUint32(offset += 2, false) != 0x45786966) return callback(-1);
var little = view.getUint16(offset += 6, false) == 0x4949;
offset += view.getUint32(offset + 4, little);
var tags = view.getUint16(offset, little);
offset += 2;
for (var i = 0; i < tags; i++)
if (view.getUint16(offset + (i * 12), little) == 0x0112)
return callback(view.getUint16(offset + (i * 12) + 8, little));
}
else if ((marker & 0xFF00) != 0xFF00) break;
else offset += view.getUint16(offset, false);
}
return callback(-1);
};
reader.readAsArrayBuffer(file.slice(0, 128 * 1024));
}
这适用于一系列图像,但是 here's one image 导致行 var tags = view.getUint16(offset, little);
与 RangeError: argument 1 accesses an index that is out of range
崩溃。
我无法判断图像是否已损坏,或者代码是否需要更多专业化。专家可以帮助我进行调整以处理此类情况吗?提前致谢!
该图像有一个 Exif 块,但它是空的。
$ exif -x 28531470-85e0855a-70c9-11e7-9bba-107a664e6635.jpeg
<exif>
</exif>
这是部分十六进制转储,
00000010: 0001 0000 ffe1 0008 4578 6966 0000 ffdb ........Exif....
当它使用 view.getUint32()
调整偏移时,它正在使用来自 ffdb
块的量化数据。
您可以尝试读取标记长度,如果它 <= 8 则跳过,
while (offset < length) {
var marker = view.getUint16(offset, false);
var markerLength = view.getUint16(offset+2, false);
....
我是一名服务器端开发人员,最近正在学习纯 JS 的技巧。我正在研究的一个实际例子是图像处理。这个问题是关于我努力检索图像方向信息以便随后旋转 and/or 反映它。
这个优秀的 SO answer 让我开始了。我写的代码是:
// used to determine orientation information
function get_orientation(file, callback) {
var reader = new FileReader();
reader.onload = function(e) {
var view = new DataView(e.target.result);
if (view.getUint16(0, false) != 0xFFD8) return callback(-2);
var length = view.byteLength, offset = 2;
while (offset < length) {
var marker = view.getUint16(offset, false);
offset += 2;
if (marker == 0xFFE1) {
if (view.getUint32(offset += 2, false) != 0x45786966) return callback(-1);
var little = view.getUint16(offset += 6, false) == 0x4949;
offset += view.getUint32(offset + 4, little);
var tags = view.getUint16(offset, little);
offset += 2;
for (var i = 0; i < tags; i++)
if (view.getUint16(offset + (i * 12), little) == 0x0112)
return callback(view.getUint16(offset + (i * 12) + 8, little));
}
else if ((marker & 0xFF00) != 0xFF00) break;
else offset += view.getUint16(offset, false);
}
return callback(-1);
};
reader.readAsArrayBuffer(file.slice(0, 128 * 1024));
}
这适用于一系列图像,但是 here's one image 导致行 var tags = view.getUint16(offset, little);
与 RangeError: argument 1 accesses an index that is out of range
崩溃。
我无法判断图像是否已损坏,或者代码是否需要更多专业化。专家可以帮助我进行调整以处理此类情况吗?提前致谢!
该图像有一个 Exif 块,但它是空的。
$ exif -x 28531470-85e0855a-70c9-11e7-9bba-107a664e6635.jpeg
<exif>
</exif>
这是部分十六进制转储,
00000010: 0001 0000 ffe1 0008 4578 6966 0000 ffdb ........Exif....
当它使用 view.getUint32()
调整偏移时,它正在使用来自 ffdb
块的量化数据。
您可以尝试读取标记长度,如果它 <= 8 则跳过,
while (offset < length) {
var marker = view.getUint16(offset, false);
var markerLength = view.getUint16(offset+2, false);
....