精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Android實現JPEG圖片壓縮后同時保留圖片的EXIF信息

移動開發 Android
ExifInterface類主要提供了讀取、寫入和縮略圖處理這三個方面的功能。通過ExifInterface,可以獲取到圖片的多種屬性,如方向(orientation)、拍攝時間(dateTime)、設備制造商(make)、設備型號(model)等。

EXIF信息是可交換圖像文件格式(Exchangeable Image File Format)的縮寫,是在JPEG格式的基礎上發展起來的,其中包含了一系列按照一定標準制定的有關圖像拍攝信息的數據和索引,包括快門速度、光圈、ISO感光度、曝光偏移、日期和時間、閃光使用情況、焦距、GPS定位數據等。

在實際開發中,對于圖片數據不論是緩存在本地磁盤還是上傳到后端,都需要先對圖片進行壓縮處理。在圖片壓縮的過程中,為了減小文件大小,一些不重要的元數據(包括EXIF信息)可能會被移除或修改。如果圖片經過壓縮處理,其原始的EXIF信息可能會丟失或不完整。

EXIF信息附加于JPEG、TIFF、RIFF等文件之中,可以記錄數碼照片的屬性信息和拍攝數據。比如記錄以下信息:

項目

資訊(舉例)

制造廠商

Canon

相機型號

Canon EOS-1Ds Mark III

影像方向

正常(upper-left)

影像解析度X

300

影像解析度Y

300

解析度單位

dpi

軟件

Adobe Photoshop CS Macintosh

最后異動時間

2005:10:06 12:53:19

YCbCrPositioning

2

曝光時間

0.00800 (1/125) sec

光圈值

F22

拍攝模式

光圈優先

ISO感光值

100

Exif資訊版本

30,32,32,31

影像拍攝時間

2005:09:25 15:00:18

影像存入時間

2005:09:25 15:00:18

曝光補償(EV+-)

0

測光模式

點測光(Spot)

閃光燈

關閉

鏡頭實體焦長

12 mm

Flashpix版本

30,31,30,30

影像色域空間

sRGB

影像尺寸X

5616 pixel

影像尺寸Y

3744 pixel

有一些壓縮工具或軟件提供了保留EXIF信息的選項。在使用這些工具進行壓縮時,可以選擇保留EXIF信息,以確保壓縮后的圖片仍然包含完整的元數據。在實際開發中我們如何進行保留EXIF信息的同時進行圖片壓縮呢?

使用ExifInterface方案

ExifInterface是Android系統中用于描述多媒體文件(如JPG格式圖片)附加信息的一個類。它主要涵蓋了拍攝時的光圈、快門、白平衡、ISO、焦距、日期時間等各種拍攝條件,以及相機品牌、型號、色彩編碼、拍攝時錄制的聲音以及全球定位系統(GPS)和縮略圖等信息。簡單來說,ExifInterface就是JPEG圖像文件+拍攝參數的結合。

ExifInterface類主要提供了讀取、寫入和縮略圖處理這三個方面的功能。通過ExifInterface,可以獲取到圖片的多種屬性,如方向(orientation)、拍攝時間(dateTime)、設備制造商(make)、設備型號(model)等。

ExifInterface類只提供了 getXXX() 和 setAttributes(String tag, String value) 這種操作單個屬性的方法,如果想將原圖片文件中的所有EXIF信息完整復制到另一個圖片中會非常繁瑣。因此有人通過反射,對所有屬性名進行遍歷,從而實現了批量操作。也算是一種解決方案,具體如下:

public static void saveExif(String oldFilePath, String newFilePath) throws Exception {
    ExifInterface oldExif = new ExifInterface(oldFilePath);
    ExifInterface newExif = new ExifInterface(newFilePath);
    Class<ExifInterface> cls = ExifInterface.class;
    Field[] fields = cls.getFields();
    for (int i = 0; i < fields.length; i++) {
        String fieldName = fields[i].getName();
        if (!TextUtils.isEmpty(fieldName) && fieldName.startsWith("TAG")) {
            String fieldValue = fields[i].get(cls).toString();
            String attribute = oldExif.getAttribute(fieldValue);
            if (attribute != null) {
                newExif.setAttribute(fieldValue, attribute);
            }
        }
    }
    //將內存中的修改寫入磁盤(IO操作)
    newExif.saveAttributes();
 }

以上方案弊端也很明顯,就是需要對文件進行多次IO操作。觀察上面方法中的兩個參數都是文件路徑,比如我們通過拍照進行圖片壓縮上傳,那么拍完照通過 onPictureTaken(byte[] data, Camera camera) 回調方法拿到圖片的 byte[] data 數據后處理是這樣的:

  • 將data緩存到磁盤,路徑為oldFilePath;(IO)
  • 將data轉換成 bitmap 進行壓縮、旋轉、剪切等操作;
  • 將處理后的 bitmap 緩存到磁盤,路徑為newFilePath;(IO)
  • 調用上面的 saveExif(oldFilePath, newFilePath) 方法; (IO)

能否只在內存中操作?發現有 ExifInterface (String filename) 和 ExifInterface (InputStream inputStream) 兩種構造方法, 進行如下改造:

public static void saveExif(byte[] srcData, String destFilePath) throws Exception {
    ExifInterface oldExif = new ExifInterface(new ByteArrayInputStream(srcData));
    ExifInterface newExif = new ExifInterface(destFilePath);
    Class<ExifInterface> cls = ExifInterface.class;
    Field[] fields = cls.getFields();
    for (int i = 0; i < fields.length; i++) {
        String fieldName = fields[i].getName();
        if (!TextUtils.isEmpty(fieldName) && fieldName.startsWith("TAG")) {
            String fieldValue = fields[i].get(cls).toString();
            String attribute = oldExif.getAttribute(fieldValue);
            if (attribute != null) {
                newExif.setAttribute(fieldValue, attribute);
            }
        }
    }
    //將內存中的修改寫入磁盤(IO操作)
    newExif.saveAttributes();
 }

使用自定義方案

不管是圖片還是其他文件,本質都是格式化的數據,都有專用的數據結構。研究下JPG的數據結構,找到 EXIF 數據塊的起始索引,然后從源文件byte[]中復制插入到目標文件byte[]對應位置中就實現了。

圖片圖片

JPEG文件的內容都開始于一個二進制的值 '0xFFD8', 并結束于二進制值'0xFFD9'. 在JPEG的數據中有好幾種類似于二進制 0xFFXX 的數據都統稱作 "標記", 代表了一段JPEG的信息數據。

0xFFD8 的意思是 SOI圖像起始(Start of image) ,是Jpeg文件的魔數(Magic Number)。每種格式的文件都有固定的Magic Number,比如.class 字節碼文件的Magic Number是 “0xCAFEBABE”。0xFFD9 則表示 EOI圖像結束 (End of image)。

0xFF+標記號(1個字節)+數據大小描述符(2個字節)+數據內容(n個字節)

對于EXIF數據,使用的是APP1標記,前兩個字節固定為 0xFFE1,后面緊跟著兩個字節記錄的是EXIF數據內容的 length + 2,假設這兩個字節的值是 24,那么EXIF數據內容的長度就是22字節。所以只要找到EXIF在數組中的起始索引,摳出來插入到新數組中去就完成了。

圖片圖片

public static byte[] cloneExif(byte[] srcData, byte[] destData) {
    if (srcData == null || srcData.length == 0 || destData == null || destData.length == 0) return null;

    ImageHeaderParser srcImageHeaderParser = new ImageHeaderParser(srcData);
    byte[] srcExifBlock = srcImageHeaderParser.getExifBlock();
    if (srcExifBlock == null || srcExifBlock.length <= 4) return null;

    LOG.d(TAG, "pictureData src: %1$s KB; dest: %2$s KB", srcData.length / 1024, destData.length / 1024);
    LOG.d(TAG, "srcExif: %s B", srcExifBlock.length);
    ImageHeaderParser destImageHeaderParser = new ImageHeaderParser(destData);
    byte[] destExifBlock = destImageHeaderParser.getExifBlock();
    if (destExifBlock != null && destExifBlock.length > 0) {
        LOG.d(TAG, "destExif: %s B", destExifBlock.length);
        //目標圖片中已有exif信息, 需要先刪除
        int exifStartIndex = destImageHeaderParser.getExifStartIndex();
        //構建新數組
        byte[] newDestData = new byte[srcExifBlock.length + destData.length - destExifBlock.length];
        //copy 1st block
        System.arraycopy(destData, 0, newDestData, 0, exifStartIndex);
        //copy 2rd block (exif)
        System.arraycopy(srcExifBlock, 0, newDestData, exifStartIndex, srcExifBlock.length);
        //copy 3th block
        int srcPos = exifStartIndex + destExifBlock.length;
        int destPos = exifStartIndex + srcExifBlock.length;
        System.arraycopy(destData, srcPos, newDestData, destPos, destData.length - srcPos);
        LOG.d(TAG, "output image Data with exif: %s KB", newDestData.length / 1024);
        return newDestData;
    } else {
        LOG.d(TAG, "destExif: %s B", 0);
        //目標圖片中沒有exif信息
        byte[] newDestData = new byte[srcExifBlock.length + destData.length];
        //copy 1st block (前兩個字節)
        System.arraycopy(destData, 0, newDestData, 0, 2);
        //copy 2rd block (exif)
        System.arraycopy(srcExifBlock, 0, newDestData, 2, srcExifBlock.length);
        //copy 3th block
        int srcPos = 2;
        int destPos = 2 + srcExifBlock.length;
        System.arraycopy(destData, srcPos, newDestData, destPos, destData.length - srcPos);
        LOG.d(TAG, "output image Data with exif: %s KB", newDestData.length / 1024);
        return newDestData;
    }

}

將原圖的數據流和壓縮處理后的數據流傳入,調用cloneExif方法,返回附加了EXIF信息的數據流,將返回的數據流存儲即得到一張帶有原EXIF信息的壓縮圖片。

「注意」上述方法只針對JPEG格式圖片,其他格式文件數據結構不同,方法可能無效。

責任編輯:武曉燕 來源: 沐雨花飛蝶
相關推薦

2024-07-04 08:26:12

AndroidJPEG圖片

2009-08-20 12:35:41

C#讀取圖片的EXIF

2020-05-07 09:45:16

前端JS圖片壓縮

2009-08-24 17:02:18

C#旋轉圖片EXIF

2020-10-20 11:12:11

Nodejs

2013-07-29 10:02:42

2018-10-29 09:24:41

Web圖片壓縮網頁加速

2023-01-15 20:28:32

前端圖片壓縮

2022-08-08 08:29:55

圖片壓縮前端互聯網

2023-11-04 12:43:44

前端圖片參數

2010-10-12 13:57:43

GoogleWebP

2013-06-27 11:16:27

Android異步加載

2022-07-17 11:22:35

前端開發圖片裁切壓縮上傳

2016-03-29 10:18:48

Android圖片代碼

2011-04-11 14:14:29

checkboxlistviewAndroid

2023-08-21 12:13:53

2020-08-21 09:58:16

谷歌Android工具

2022-06-14 07:29:51

squoosh壓縮工具開源

2013-05-15 10:27:05

R語言

2011-05-30 13:23:11

Android 動畫
點贊
收藏

51CTO技術棧公眾號

捆绑调教日本一区二区三区| 中文字幕第2页| 成人精品动漫一区二区三区| 欧美日韩性视频在线| 精品不卡在线| 亚洲最大成人av| 亚洲精品1234| www.欧美精品| 精品国产人妻一区二区三区| 欧美与亚洲与日本直播| 亚洲精品国产视频| 欧美日韩精品久久| 99在线无码精品入口| 久久aⅴ国产紧身牛仔裤| 中文字幕在线视频日韩| 青青草视频网站| 亚洲成a人片777777久久| 亚洲第一综合色| 特级毛片在线免费观看| 天天操天天干天天插| 久久国产精品99精品国产| 欧美激情亚洲精品| 永久免费看片视频教学| 清纯唯美亚洲经典中文字幕| 91精品国产欧美一区二区成人 | 国产精品国产自产拍高清av水多| 国产乱国产乱老熟300| 精品理论电影| 日韩久久精品成人| 18禁一区二区三区| 亚洲午夜国产成人| 在线看日韩精品电影| 精品少妇一区二区三区在线| 26uuu亚洲电影在线观看| 久久综合狠狠综合久久综合88| 亚洲www在线观看| 一区二区日韩视频| 日韩av一区二区三区| 韩日精品中文字幕| 欧美日韩偷拍视频| 亚洲乱码在线| 久久精品成人欧美大片古装| 亚洲精品在线视频免费观看| 日韩在线观看中文字幕| 欧美美女喷水视频| 三上悠亚在线一区二区| 日本在线精品| 在线精品国精品国产尤物884a| 每日在线更新av| 超碰激情在线| 五月婷婷综合在线| 欧美久久久久久久久久久久久| 午夜伦理大片视频在线观看| 亚洲视频1区2区| 一区二区三区四区视频在线观看 | 国产欧美日韩精品a在线观看| 久久综合中文色婷婷| 人人妻人人澡人人爽久久av| 粉嫩av一区二区三区| 97免费资源站| 人妻丰满熟妇av无码区hd| 丁香婷婷综合激情五月色| 国产精品大全| 亚洲色图 校园春色| 成人毛片老司机大片| 精品九九九九| 毛片免费在线观看| 国产精品入口麻豆九色| 曰韩不卡视频| 欧美性猛片xxxxx免费中国| 午夜欧美在线一二页| 欧美日韩性生活片| 亚洲最大网站| 欧美日韩一区二区三区四区 | 国产天堂第一区| 免费一级片91| 51蜜桃传媒精品一区二区| 成人免费视频国产| 久久青草国产手机看片福利盒子 | 亚洲影视一区二区三区| 欧美激情视频播放| 国产欧美一区二区三区在线看蜜臂| 另类图片国产| 国产一区二区在线免费| 精品人妻少妇AV无码专区| www.99精品| 日韩精品一区二区三区丰满| 久操视频在线观看| 五月天丁香久久| 久久国产激情视频| 国产毛片久久久| 亚洲香蕉成人av网站在线观看 | 国产精品久久久久久在线观看| 外国成人在线视频| 日韩在线欧美在线| 99视频在线看| 久久99国产精品尤物| 国产精品一区而去| 在线激情网站| 亚洲va韩国va欧美va精品| 粉色视频免费看| 蜜桃久久久久| 久久久精品欧美| 四虎精品永久在线| 国产精品一色哟哟哟| 久久免费一区| 制服丝袜在线播放| 欧美综合色免费| 亚洲国产精品无码久久久久高潮| 欧美激情另类| 国产91精品最新在线播放| 精品国产无码AV| 亚洲国产精品成人久久综合一区| 日韩网站在线免费观看| 另类一区二区| 亚洲视频在线免费看| 九九热国产在线| 久久国产婷婷国产香蕉| 麻豆精品传媒视频| 久久av色综合| 欧美一区二区三区婷婷月色| 天天躁日日躁aaaa视频| 亚洲日本免费| 97超级在线观看免费高清完整版电视剧| 久久99久久| 午夜电影久久久| 国产ts在线观看| 外国成人免费视频| 国产精品美女无圣光视频| 三级国产在线观看| 亚洲一区二区在线免费看| 做a视频在线观看| 欧美性感美女一区二区| 日本乱人伦a精品| 午夜国产在线视频| 午夜婷婷国产麻豆精品| 欧美xxxxx少妇| 国产精品分类| 91在线看网站| 性欧美video高清bbw| 日韩一区二区精品在线观看| jizz日本在线播放| 日本女人一区二区三区| 日韩av免费电影| 欧美第一视频| 亚洲色图色老头| 69xxxx国产| 国产性色一区二区| 欧美日韩在线免费播放| 国产一区二区观看| 国产成人精品在线| 大片免费播放在线视频| 欧洲精品在线观看| 免费视频91蜜桃| 免费欧美在线视频| 自拍偷拍亚洲色图欧美| 国产精品欧美一区二区三区不卡| 日韩在线观看精品| 国产视频第二页| 一区二区三区在线视频播放| 久久久久亚洲av无码网站| 亚洲第一区色| 蜜桃传媒视频麻豆第一区免费观看| 精品众筹模特私拍视频| 亚洲成成品网站| 天堂中文在线网| 国产偷v国产偷v亚洲高清| 日韩亚洲在线视频| 成人羞羞网站| 不卡一区二区三区四区五区| 国产后进白嫩翘臀在线观看视频| 亚洲国产精品va在看黑人| www.国产com| 中文字幕精品一区二区三区精品| 九九热99视频| 在线播放亚洲| 亚洲精品乱码视频| 日韩欧美中文字幕在线视频| 97超级碰碰碰久久久| 久久精品色图| 91精品国产乱| 国产成人在线播放视频| 国产清纯在线一区二区www| 亚洲一级片网站| 国内揄拍国内精品久久| 免费观看成人在线| 高清国产一区二区三区四区五区| 国模精品视频一区二区| 成人免费在线电影| 日韩你懂的在线观看| 久久久成人免费视频| 国产精品久久99| 成人手机在线免费视频| 毛片av一区二区| 黄页网站大全在线观看| 日韩一区三区| 精品久久sese| 精品久久亚洲| 国产成人综合精品在线| 免费污视频在线| 中文字幕最新精品| 无码精品视频一区二区三区| 在线电影院国产精品| 国产一区二区99| 亚洲人成在线观看一区二区| 人妻精品久久久久中文字幕| 国产精品一区二区在线播放| 日本xxxxxxx免费视频| 国产精品vip| 亚洲精品中字| 亚洲欧洲免费| 好吊色欧美一区二区三区| 日韩国产大片| 欧洲日韩成人av| heyzo一区| 欧美精品在线观看91| 国产毛片av在线| 日韩av中文字幕在线免费观看| 国产熟女一区二区三区四区| 在线观看成人免费视频| 99热在线观看免费精品| 亚洲一区二区三区在线播放| 性欧美疯狂猛交69hd| 国产日本欧洲亚洲| 中文字幕一区二区久久人妻网站| 国产激情精品久久久第一区二区 | 久久国产精品网| 综合国产精品| 中文字幕一区二区三区四区五区| 免费久久久久久久久| 精品视频在线观看| 91午夜精品| 97人人干人人| 蜜桃精品一区二区三区| 成人免费在线视频网址| jvid一区二区三区| 国产精品伦子伦免费视频| 欧美电影免费观看| 国产福利成人在线| 二区三区不卡| 国产不卡av在线| 欧美电影h版| 国产精品91久久| 高清av一区| 国产欧美久久一区二区| 99久久er| 国产精品美女在线| 少妇精品视频在线观看| 国产欧美日韩专区发布| 日韩免费大片| 91超碰在线免费观看| 精品视频在线播放一区二区三区| 91免费欧美精品| 久久久久久亚洲精品美女| 99精品欧美一区二区三区| 亚洲福利合集| 国产在线一区二区三区四区 | 亚洲午夜激情| 亚洲视频在线免费| 污污污污污污www网站免费| 国产一区美女| 777精品久无码人妻蜜桃| 久久国产免费| 9l视频白拍9色9l视频| 激情av综合网| 日本久久久久久久久久| 99re在线精品| 懂色av粉嫩av浪潮av| 亚洲日韩欧美一区二区在线| 麻豆91精品91久久久| 精品欧美一区二区三区| 欧美日韩 一区二区三区| 欧美丰满少妇xxxbbb| 亚洲国产精彩视频| 精品亚洲永久免费精品| 最新电影电视剧在线观看免费观看 | 日韩精品视频一二三| 国产在线视频不卡二| 美女伦理水蜜桃4| 久久久久久久综合色一本| 成年人视频软件| 亚洲国产日韩综合久久精品| 国产午夜免费福利| 欧美日韩高清一区二区| 黄色片一区二区| 中文字幕欧美国内| 精品精品导航| 国产精品极品美女粉嫩高清在线| 国产精选久久| 久久久综合亚洲91久久98| 亚洲电影影音先锋| 免费黄色日本网站| 国产中文字幕精品| 黄色正能量网站| 亚洲人成伊人成综合网小说| 亚洲天堂一区在线| 欧美一区二区三区公司| 欧美成熟毛茸茸| 欧美高清激情视频| 国产综合色在线观看| 99精品欧美一区二区三区| 精品72久久久久中文字幕| 2022中文字幕| 美女一区二区三区| 久久亚洲AV成人无码国产野外| 亚洲精品成人a在线观看| 国产美女www爽爽爽| 亚洲成年人在线| 精品国产白色丝袜高跟鞋| 国产成人激情视频| 57pao国产一区二区| 爱爱爱视频网站| 日韩中文字幕一区二区三区| 国产av一区二区三区传媒| 亚洲人被黑人高潮完整版| 最近中文字幕在线观看| 亚洲精品狠狠操| 青草av在线| 91久久久久久久久久久久久| jizzjizz欧美69巨大| 日韩欧美国产免费| 成人精品一区二区三区中文字幕| 日本美女黄色一级片| 色www精品视频在线观看| 特级丰满少妇一级aaaa爱毛片| 久久躁狠狠躁夜夜爽| 懂色aⅴ精品一区二区三区| 欧美一区二区视频在线| 国产欧美日韩一区二区三区在线| 蜜臀aⅴ国产精品久久久国产老师| 亚洲欧洲精品成人久久奇米网| av首页在线观看| 亚洲午夜av久久乱码| 成人福利av| 老牛影视免费一区二区| 999亚洲国产精| 欧美在线一级片| 精品久久久久久久久久久久久久| 国精品人妻无码一区二区三区喝尿| 超碰91人人草人人干| 成人在线视频国产| 色撸撸在线观看| 国产一区二区伦理片| 亚洲黄色网址大全| 欧美日韩免费高清一区色橹橹| av在线播放网站| 国产日韩欧美一二三区| 欧美3p视频| 交换做爰国语对白| 一区二区三区在线免费观看| 午夜精品久久久久久久99热黄桃| 欧美成人午夜剧场免费观看| 欧美二区观看| 九色自拍视频在线观看| 成人av电影免费在线播放| 国产成人精品一区二三区| 日韩av影片在线观看| 春暖花开亚洲一区二区三区| 日韩精品一区二区三区四区五区| 日韩电影一区二区三区| 少妇太紧太爽又黄又硬又爽小说| 69久久99精品久久久久婷婷| 伊人影院在线视频| 好看的日韩精品| 日韩高清中文字幕一区| 黄色片子在线观看| 亚洲成人av在线播放| 中文av在线全新| 少妇免费毛片久久久久久久久| 久久精品国产一区二区三| 东方av正在进入| 欧美精品一区二区三区蜜臀| 成人爱爱网址| 男女啪啪的视频| 成人激情文学综合网| www.欧美色| 免费97视频在线精品国自产拍| 国产精品对白| 欧美伦理片在线看| 一区二区三区精品视频在线| 天天躁日日躁狠狠躁喷水| 国产精品户外野外| 狠狠久久婷婷| 国产熟女一区二区| 精品久久国产字幕高潮| 国产精品高清乱码在线观看| 欧美三级午夜理伦三级老人| 99精品国产99久久久久久白柏| 在线观看免费中文字幕| 欧美激情亚洲国产| 操欧美老女人| 麻豆精品国产传媒av| 欧美三区在线观看| а√天堂8资源中文在线| 亚洲黄色一区二区三区| 丰满放荡岳乱妇91ww| 波多野结衣一区二区三区四区| 欧美老妇交乱视频| 精品美女在线视频| 亚洲一级Av无码毛片久久精品|