在客户端用JavaScript访问JPEG EXIF旋转数据

在客户端用JavaScript访问JPEG EXIF旋转数据

我想旋转照片的基础上,他们的原始旋转,由相机设置的JPEG EXIF图像数据。诀窍是,所有这些都应该发生在浏览器中,使用JavaScript和<canvas>.

JavaScript如何访问JPEG,本地文件API对象,本地<img>或遥远<img>,EXIF数据读取旋转信息?

服务器端的答案不太好,我正在寻找客户端解决办法。


达令说
浏览 402回答 3
3回答

HUWWW

如果您只想要方向标签,而不想包含另一个巨大的javascript库,那么我编写了一些代码,尽可能快地只提取方向标记(它使用DataView和readAsArrayBuffer它可以在IE10+中使用,但您可以为旧浏览器编写自己的数据读取器):function&nbsp;getOrientation(file,&nbsp;callback)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;reader&nbsp;=&nbsp;new&nbsp;FileReader(); &nbsp;&nbsp;&nbsp;&nbsp;reader.onload&nbsp;=&nbsp;function(e)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;view&nbsp;=&nbsp;new&nbsp;DataView(e.target.result); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(view.getUint16(0,&nbsp;false)&nbsp;!=&nbsp;0xFFD8) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;callback(-2); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;length&nbsp;=&nbsp;view.byteLength,&nbsp;offset&nbsp;=&nbsp;2; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(offset&nbsp;<&nbsp;length)&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(view.getUint16(offset+2,&nbsp;false)&nbsp;<=&nbsp;8)&nbsp;return&nbsp;callback(-1); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;marker&nbsp;=&nbsp;view.getUint16(offset,&nbsp;false); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;offset&nbsp;+=&nbsp;2; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(marker&nbsp;==&nbsp;0xFFE1)&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(view.getUint32(offset&nbsp;+=&nbsp;2,&nbsp;false)&nbsp;!=&nbsp;0x45786966)&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;callback(-1); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;little&nbsp;=&nbsp;view.getUint16(offset&nbsp;+=&nbsp;6,&nbsp;false)&nbsp;==&nbsp;0x4949; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;offset&nbsp;+=&nbsp;view.getUint32(offset&nbsp;+&nbsp;4,&nbsp;little); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;tags&nbsp;=&nbsp;view.getUint16(offset,&nbsp;little); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;offset&nbsp;+=&nbsp;2; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(var&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;<&nbsp;tags;&nbsp;i++) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(view.getUint16(offset&nbsp;+&nbsp;(i&nbsp;*&nbsp;12),&nbsp;little)&nbsp;==&nbsp;0x0112) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;callback(view.getUint16(offset&nbsp;+&nbsp;(i&nbsp;*&nbsp;12)&nbsp;+&nbsp;8,&nbsp;little)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if&nbsp;((marker&nbsp;&&nbsp;0xFF00)&nbsp;!=&nbsp;0xFF00) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;offset&nbsp;+=&nbsp;view.getUint16(offset,&nbsp;false); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;callback(-1); &nbsp;&nbsp;&nbsp;&nbsp;}; &nbsp;&nbsp;&nbsp;&nbsp;reader.readAsArrayBuffer(file);}//&nbsp;usage:var&nbsp;input&nbsp;=&nbsp;document.getElementById('input');input.onchange&nbsp;=&nbsp;function(e)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;getOrientation(input.files[0],&nbsp;function(orientation)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alert('orientation:&nbsp;'&nbsp;+&nbsp;orientation); &nbsp;&nbsp;&nbsp;&nbsp;});}<input&nbsp;id='input'&nbsp;type='file'&nbsp;/>价值:-2:&nbsp;not&nbsp;jpeg-1:&nbsp;not&nbsp;defined对于使用类型记录的用户,可以使用以下代码:export&nbsp;const&nbsp;getOrientation&nbsp;=&nbsp;(file:&nbsp;File,&nbsp;callback:&nbsp;Function)&nbsp;=>&nbsp;{ &nbsp;&nbsp;var&nbsp;reader&nbsp;=&nbsp;new&nbsp;FileReader(); &nbsp;&nbsp;reader.onload&nbsp;=&nbsp;(event:&nbsp;ProgressEvent)&nbsp;=>&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!&nbsp;event.target)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;file&nbsp;=&nbsp;event.target&nbsp;as&nbsp;FileReader; &nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;view&nbsp;=&nbsp;new&nbsp;DataView(file.result&nbsp;as&nbsp;ArrayBuffer); &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(view.getUint16(0,&nbsp;false)&nbsp;!=&nbsp;0xFFD8)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;callback(-2); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;length&nbsp;=&nbsp;view.byteLength&nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;offset&nbsp;=&nbsp;2; &nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(offset&nbsp;<&nbsp;length) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(view.getUint16(offset+2,&nbsp;false)&nbsp;<=&nbsp;8)&nbsp;return&nbsp;callback(-1); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;marker&nbsp;=&nbsp;view.getUint16(offset,&nbsp;false); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;offset&nbsp;+=&nbsp;2; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(marker&nbsp;==&nbsp;0xFFE1)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(view.getUint32(offset&nbsp;+=&nbsp;2,&nbsp;false)&nbsp;!=&nbsp;0x45786966)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;callback(-1); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;little&nbsp;=&nbsp;view.getUint16(offset&nbsp;+=&nbsp;6,&nbsp;false)&nbsp;==&nbsp;0x4949; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;offset&nbsp;+=&nbsp;view.getUint32(offset&nbsp;+&nbsp;4,&nbsp;little); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;tags&nbsp;=&nbsp;view.getUint16(offset,&nbsp;little); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;offset&nbsp;+=&nbsp;2; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(let&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;<&nbsp;tags;&nbsp;i++)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(view.getUint16(offset&nbsp;+&nbsp;(i&nbsp;*&nbsp;12),&nbsp;little)&nbsp;==&nbsp;0x0112)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;callback(view.getUint16(offset&nbsp;+&nbsp;(i&nbsp;*&nbsp;12)&nbsp;+&nbsp;8,&nbsp;little)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;if&nbsp;((marker&nbsp;&&nbsp;0xFF00)&nbsp;!=&nbsp;0xFF00)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;offset&nbsp;+=&nbsp;view.getUint16(offset,&nbsp;false); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;callback(-1); &nbsp;&nbsp;}; &nbsp;&nbsp;reader.readAsArrayBuffer(file);}
打开App,查看更多内容
随时随地看视频慕课网APP