flex壓縮圖片exif信息(作者/相機(jī))丟失問題解決
更新時(shí)間:2013年02月18日 11:12:10 作者:
使用flex的jpegencoder對(duì)圖片進(jìn)行壓縮的時(shí)候,exif信息會(huì)丟失這一點(diǎn)確實(shí)令人郁悶啊,此問題應(yīng)當(dāng)如何解決呢?經(jīng)研究jpeg的文檔,最終解決這個(gè)問題,曬出來與大家分享希望可以幫助到你們
在用flex的jpegencoder對(duì)圖片進(jìn)行壓縮的時(shí)候,exif信息會(huì)丟失,也就是圖片的作者,用的相機(jī),神馬的,全部都沒有了,怎么辦呢?
經(jīng)研究jpeg的文檔,最終解決這個(gè)問題
1.jpeg的文件格式,分成一個(gè)一個(gè)frame,每個(gè)frame以0xFF打頭,然后跟著一個(gè)標(biāo)識(shí)未,比如0xFFD8表示文件的開始,0xFFD9表示文件結(jié)束,緊接著標(biāo)識(shí)位的是這個(gè)frame的長(zhǎng)度,長(zhǎng)度不包括0xFF和標(biāo)識(shí)位,但包括這個(gè)2個(gè)字節(jié)的長(zhǎng)度,比如一個(gè)frame開始了,先是一個(gè)0xFF然后是一個(gè)0xXX,然后是兩個(gè)0x0010,說明這個(gè)frame的長(zhǎng)度是16,整個(gè)frame的長(zhǎng)度其實(shí)是18,
2.我們要研究的是圖片的exif信息,他的標(biāo)識(shí)位是0xE1
而且這個(gè)0xE1有兩種情況,第一種,就是緊跟著文件頭,就是0xE1,第二種,就是在0xE1之前還有一個(gè)0xE0,
所以在把這個(gè)byteArray在如到圖片對(duì)象之前,先要獲取到這個(gè)0xE1的frame的所有數(shù)據(jù),代碼如下:
//獲取0xFFE1 app1也就是exif信息
var tempData:ByteArray = new ByteArray();
//這里的e.target.data是圖片的原始byteArray
tempData.writeBytes(e.target.data,0,e.target.data.bytesAvailable);
tempData.position = 3; //讀取第四個(gè)字節(jié)
var exif:Number = tempData.readUnsignedByte();
if(exif == 0xE1) { //看這個(gè)字節(jié)是不是0xE1
this.Debug("有exif信息");
//讀一個(gè)長(zhǎng)度
var exifLength:Number = tempData.readUnsignedShort();
file_item.exifArray.writeBytes(tempData,tempData.position-2,exifLength); //如果是,將exif信息讀入一個(gè)文件對(duì)象
} else if(exif == 0xE0) { //是e0,那么跳過這個(gè)frame,看下邊
tempData.position = 4;
var e0Length:Number = tempData.readUnsignedShort();
tempData.position = 4+e0Length;//跳過e0
tempData.position += 1;//跳過0xff
var isEx:Number = tempData.readUnsignedByte();
if(isEx==0xE1) {
var len:Number = tempData.readUnsignedShort();
file_item.exifArray.writeBytes(tempData,tempData.position-2,len);
}
}
然后處理完了這些,我們就需要把這段frame給插到壓縮之后的byteArray里
代碼的邏輯應(yīng)該一目了然的,嘿嘿
if(file_item.exifArray.length>0) { //寫入exif信息
var desData:ByteArray = new ByteArray();
desData.writeBytes(oldData,0,2);//0xffd8
desData.writeByte(0xff);
desData.writeByte(0xe1);
desData.writeBytes(file_item.exifArray,0,file_item.exifArray.bytesAvailable);
desData.writeBytes(oldData,2,oldData.bytesAvailable);
desData.position = 0;
this.uploadFileTest(desData,file_item);
} else {
this.uploadFileTest(e.target.ba,file_item);
}
經(jīng)研究jpeg的文檔,最終解決這個(gè)問題
1.jpeg的文件格式,分成一個(gè)一個(gè)frame,每個(gè)frame以0xFF打頭,然后跟著一個(gè)標(biāo)識(shí)未,比如0xFFD8表示文件的開始,0xFFD9表示文件結(jié)束,緊接著標(biāo)識(shí)位的是這個(gè)frame的長(zhǎng)度,長(zhǎng)度不包括0xFF和標(biāo)識(shí)位,但包括這個(gè)2個(gè)字節(jié)的長(zhǎng)度,比如一個(gè)frame開始了,先是一個(gè)0xFF然后是一個(gè)0xXX,然后是兩個(gè)0x0010,說明這個(gè)frame的長(zhǎng)度是16,整個(gè)frame的長(zhǎng)度其實(shí)是18,
2.我們要研究的是圖片的exif信息,他的標(biāo)識(shí)位是0xE1
而且這個(gè)0xE1有兩種情況,第一種,就是緊跟著文件頭,就是0xE1,第二種,就是在0xE1之前還有一個(gè)0xE0,
所以在把這個(gè)byteArray在如到圖片對(duì)象之前,先要獲取到這個(gè)0xE1的frame的所有數(shù)據(jù),代碼如下:
復(fù)制代碼 代碼如下:
//獲取0xFFE1 app1也就是exif信息
var tempData:ByteArray = new ByteArray();
//這里的e.target.data是圖片的原始byteArray
tempData.writeBytes(e.target.data,0,e.target.data.bytesAvailable);
tempData.position = 3; //讀取第四個(gè)字節(jié)
var exif:Number = tempData.readUnsignedByte();
if(exif == 0xE1) { //看這個(gè)字節(jié)是不是0xE1
this.Debug("有exif信息");
//讀一個(gè)長(zhǎng)度
var exifLength:Number = tempData.readUnsignedShort();
file_item.exifArray.writeBytes(tempData,tempData.position-2,exifLength); //如果是,將exif信息讀入一個(gè)文件對(duì)象
} else if(exif == 0xE0) { //是e0,那么跳過這個(gè)frame,看下邊
tempData.position = 4;
var e0Length:Number = tempData.readUnsignedShort();
tempData.position = 4+e0Length;//跳過e0
tempData.position += 1;//跳過0xff
var isEx:Number = tempData.readUnsignedByte();
if(isEx==0xE1) {
var len:Number = tempData.readUnsignedShort();
file_item.exifArray.writeBytes(tempData,tempData.position-2,len);
}
}
然后處理完了這些,我們就需要把這段frame給插到壓縮之后的byteArray里
代碼的邏輯應(yīng)該一目了然的,嘿嘿
復(fù)制代碼 代碼如下:
if(file_item.exifArray.length>0) { //寫入exif信息
var desData:ByteArray = new ByteArray();
desData.writeBytes(oldData,0,2);//0xffd8
desData.writeByte(0xff);
desData.writeByte(0xe1);
desData.writeBytes(file_item.exifArray,0,file_item.exifArray.bytesAvailable);
desData.writeBytes(oldData,2,oldData.bytesAvailable);
desData.position = 0;
this.uploadFileTest(desData,file_item);
} else {
this.uploadFileTest(e.target.ba,file_item);
}
相關(guān)文章
Flex調(diào)Javascript打開新窗口示例代碼
Flex通過調(diào)用Javascript打開全屏的新窗口新窗口示例代碼 ,具體實(shí)現(xiàn)代碼如下,感興趣的朋友可以參考下,希望對(duì)大家有所幫助2013-08-08
flex中使用RadioButtonGroup時(shí)取出所選項(xiàng)的值的方法
flex中的RadioButtonGroup想必大家并不陌生吧,在本文將為大家介紹下在使用RadioButtonGroup時(shí)如何取出所選項(xiàng)的值,感興趣的朋友可以參考下2013-12-12
flex調(diào)用webservice中的自定義類的方法
flex如何調(diào)用webservice中的自定義類,下面有個(gè)不錯(cuò)的示例,不了解的朋友可以參考下2014-01-01
FLEX ArrayCollection刪除過濾的數(shù)據(jù)問題解決
ArrayCollection添加過濾器后,調(diào)用removeItemAt()是無法刪除的,下面有個(gè)不錯(cuò)的解決方法,大家可以參考下2014-06-06
flex4 panel去掉標(biāo)題設(shè)置透明度效果代碼
首先:去掉Panel的標(biāo)題,其次:設(shè)置透明度這個(gè)說了也是啰嗦,大家都會(huì),不過還是提一下吧,具體請(qǐng)祥看本文2013-05-05
Flex DataGrid 偽合并單元格實(shí)現(xiàn)思路
本節(jié)主要介紹了Flex DataGrid 偽合并單元格實(shí)現(xiàn)思路,需要的朋友可以參考下2014-07-07
Flex4 使用itemRenderer 為Tree加線具體實(shí)現(xiàn)
本文為大家詳細(xì)介紹下Flex4如何使用itemRenderer 為Tree加線,感興趣的朋友可以參考下2013-12-12

