我想根據相機在JPEG EXIF圖像數據中設置的原始旋轉旋轉照片。訣竅是,所有這些都應該發生在瀏覽器中,使用JavaScript和<canvas>
。在客戶端使用JavaScript訪問JPEG EXIF旋轉數據
JavaScript如何訪問JPEG,本地文件API對象,本地<img>
或遠程<img>
,EXIF數據讀取旋轉信息?
服務器端答案不正確;我正在尋找客戶端解決方案。
我想根據相機在JPEG EXIF圖像數據中設置的原始旋轉旋轉照片。訣竅是,所有這些都應該發生在瀏覽器中,使用JavaScript和<canvas>
。在客戶端使用JavaScript訪問JPEG EXIF旋轉數據
JavaScript如何訪問JPEG,本地文件API對象,本地<img>
或遠程<img>
,EXIF數據讀取旋轉信息?
服務器端答案不正確;我正在尋找客戶端解決方案。
如果只想方向標籤,沒有別的,不喜歡有另一個巨大的JavaScript庫我寫一點代碼,只提取方向標籤儘可能快地(它使用數據視圖和readAsArrayBuffer
這是在IE10 +,但您可以編寫舊版本瀏覽器自己的數據讀取器):
function getOrientation(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)
{
if (view.getUint16(offset+2, false) <= 8) return callback(-1);
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);
}
// usage:
var input = document.getElementById('input');
input.onchange = function(e) {
getOrientation(input.files[0], function(orientation) {
alert('orientation: ' + orientation);
});
}
<input id='input' type='file' />
值:
-2: not jpeg
-1: not defined
如果你想跨瀏覽器,最好的辦法就是在服務器上做。你可以有一個接受文件URL並返回EXIF數據的API; PHP has a module for that。
這可以使用Ajax來完成,因此它對用戶來說是無縫的。如果您不關心跨瀏覽器兼容性,並且可以依賴HTML5文件功能,請查看庫JsJPEGmeta,以便您可以使用原生JavaScript獲取該數據。
[本文](http://benno.id的最後一部分。 au/blog/2009/12/30/html5-fileapi-jpegmeta)解釋了圖書館的工作原理。 –
謝謝。 JS腳本看起來很甜美。我沒有使用PHP(其實我討厭它),我正在尋找純粹的客戶端JavaScript解決方案。 –
這裏是一個參考實現https://github.com/miohtama/Krusovice/blob/master/src/tools/resizer.js –
您可以使用this library結合HTML5文件API:http://jsfiddle.net/xQnMd/1/。
$("input").change(function() {
var file = this.files[0]; // file
fr = new FileReader; // to read file contents
fr.onloadend = function() {
// get EXIF data
var exif = EXIF.readFromBinaryFile(new BinaryFile(this.result));
// alert a value
alert(exif.Make);
};
fr.readAsBinaryString(file); // read the file
});
謝謝。問題中的JS lib看起來有點過時,但可能會起作用。 –
另請參閱我剛剛寫的一個文件上傳小部件演示。它使用上面提到的EXIF.js庫來讀取圖像文件的元數據中的EXIF方向標誌。根據這些信息,它使用畫布元素應用旋轉... http://sandbox.juurlink.org/html5imageuploader –
試圖在我的項目中包含binaryajax.js導致訪問被拒絕錯誤。 –
Firefox 26支持image-orientation: from-image
:圖像根據EXIF數據顯示爲縱向或橫向。 (見sethfowler.org/blog/2013/09/13/new-in-firefox-26-css-image-orientation。)
感謝您的錯誤報告鏈接。我爲它出演過,以便Chrome團隊知道更多人想要這個。 – DemiImp
@Sam Dutton,似乎我需要你的幫助。看看這個:https://stackoverflow.com/questions/45650465/how-do-i-fix-orientation-upload-image-before-saving-in-folder-javascript –
https://github.com/blueimp/JavaScript-Load-Image是一個現代的JavaScript庫,不僅可以提取Exif方向標誌 - 它還可以在客戶端正確鏡像/旋轉JPEG圖像。
我只是解決了這個庫同樣的問題:JS Client-Side Exif Orientation: Rotate and Mirror JPEG Images
似乎我需要你的幫助。看看這個:https://stackoverflow.com/questions/45650465/how-do-i-fix-orientation-upload-image-before-saving-in-folder-javascript –
退房我寫了一個模塊(你可以在瀏覽器中使用它),它的EXIF方向轉換爲CSS變換:https://github.com/Sobesednik/exif2css
也有這個節點程序生成所有的方向的JPEG裝置:https://github.com/Sobesednik/generate-exif-fixtures
好模塊!但是,它首先從JPEG獲取EXIF信息的方式如何? –
@MikkoOhtamaa感謝和不支持,你必須使用exif-js或exiftool服務器端 – zavr
這很有用。但在我看來,它只適用於人像照片,而不是風景照片。 –
我上傳擴展代碼以顯示照片的Android相機上的HTML正常的一些img標籤右旋轉,特別是對於寬度比寬度高的img標籤。我知道這段代碼很醜,但是你不需要安裝任何其他的包。(我使用上面的代碼以獲得EXIF旋轉值,謝謝。)
function getOrientation(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);
}
var isChanged = false;
function rotate(elem, orientation) {
if (isIPhone()) return;
var degree = 0;
switch (orientation) {
case 1:
degree = 0;
break;
case 2:
degree = 0;
break;
case 3:
degree = 180;
break;
case 4:
degree = 180;
break;
case 5:
degree = 90;
break;
case 6:
degree = 90;
break;
case 7:
degree = 270;
break;
case 8:
degree = 270;
break;
}
$(elem).css('transform', 'rotate('+ degree +'deg)')
if(degree == 90 || degree == 270) {
if (!isChanged) {
changeWidthAndHeight(elem)
isChanged = true
}
} else if ($(elem).css('height') > $(elem).css('width')) {
if (!isChanged) {
changeWidthAndHeightWithOutMargin(elem)
isChanged = true
} else if(degree == 180 || degree == 0) {
changeWidthAndHeightWithOutMargin(elem)
if (!isChanged)
isChanged = true
else
isChanged = false
}
}
}
function changeWidthAndHeight(elem){
var e = $(elem)
var width = e.css('width')
var height = e.css('height')
e.css('width', height)
e.css('height', width)
e.css('margin-top', ((getPxInt(height) - getPxInt(width))/2).toString() + 'px')
e.css('margin-left', ((getPxInt(width) - getPxInt(height))/2).toString() + 'px')
}
function changeWidthAndHeightWithOutMargin(elem){
var e = $(elem)
var width = e.css('width')
var height = e.css('height')
e.css('width', height)
e.css('height', width)
e.css('margin-top', '0')
e.css('margin-left', '0')
}
function getPxInt(pxValue) {
return parseInt(pxValue.trim("px"))
}
function isIPhone(){
return (
(navigator.platform.indexOf("iPhone") != -1) ||
(navigator.platform.indexOf("iPod") != -1)
);
}
,然後使用諸如
$("#banner-img").change(function() {
var reader = new FileReader();
getOrientation(this.files[0], function(orientation) {
rotate($('#banner-img-preview'), orientation, 1)
});
reader.onload = function (e) {
$('#banner-img-preview').attr('src', e.target.result)
$('#banner-img-preview').css('display', 'inherit')
};
// read the image file as a data URL.
reader.readAsDataURL(this.files[0]);
});
爲2,4,5,7得到正確的圖像,你需要旋轉和翻轉,對不對? –
我的圖像的方向是3 ..我如何設置方向爲1? – Lucy
我試過使用幾個JPG格式,而且大多數都返回-1,不管它們的方向如何。這是否意味着它無法訪問EXIF數據? – SimeriaIonut