精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

欧美亚洲另类色图| 超碰在线97av| 老司机精品免费视频| 在线日韩三级| 亚洲一区二区综合| 看高清中日韩色视频| 中文字幕av无码一区二区三区| 久久亚洲成人| 亚洲精品在线电影| 北条麻妃视频在线| 97caopor国产在线视频| www国产精品av| 成人美女免费网站视频| 日本熟伦人妇xxxx| 日韩激情免费| 亚洲福利在线视频| 在线免费视频一区| av第一福利在线导航| 亚洲国产精品精华液ab| 成人资源av| 波多野结衣av无码| 黄色亚洲大片免费在线观看| 亚洲最新在线视频| 国产午夜在线一区二区三区| 久久亚洲精品爱爱| 亚洲第一福利视频在线| 中国人体摄影一区二区三区| 深夜视频在线免费| 国产精品综合二区| 国产成人午夜视频网址| 麻豆一区二区三区精品视频| 热久久天天拍国产| 精品小视频在线| 国内精品免费视频| 99tv成人影院| 91国模大尺度私拍在线视频 | 亚洲精品合集| 欧美tickling挠脚心丨vk| 另类小说色综合| 午夜激情在线播放| 亚洲一区二区三区激情| 在线国产99| 国产98在线| 91玉足脚交白嫩脚丫在线播放| 亚洲tv在线观看| 波多野结衣电影在线播放| 一区二区三区国产盗摄 | 久久久久久亚洲中文字幕无码| 久久视频免费| 在线播放一区二区三区| 欧美日韩大尺度| 在线男人天堂| 精品毛片三在线观看| 亚洲色成人www永久在线观看| 麻豆视频在线免费观看| 国产精品毛片无遮挡高清| 日本一区二区三区免费观看| 色中色在线视频| av中文字幕不卡| 国产日韩在线一区二区三区| 亚洲国产一二三区| 国产iv一区二区三区| 亚洲一区二区在线播放| 国产男女裸体做爰爽爽| 国产综合色精品一区二区三区| 国产精品久久久久免费a∨大胸 | 日本在线视频站| 中文字幕av在线一区二区三区| 日韩av一区二区三区美女毛片| 男男电影完整版在线观看| av一二三不卡影片| 久久影视中文粉嫩av| 三级理论午夜在线观看| 91视频一区二区| 欧美激情导航| www免费网站在线观看| 中文字幕不卡的av| 在线观看免费黄色片| 在线视频观看国产| 一区二区激情视频| 91专区在线观看| 国产超碰精品| 欧美日韩精品一区二区在线播放| 天天干天天操天天做| 国产精品一区二区三区四区在线观看 | 制服丨自拍丨欧美丨动漫丨| 亚洲精品成人| 久久露脸国产精品| 无码aⅴ精品一区二区三区| 日本v片在线高清不卡在线观看| 国产噜噜噜噜噜久久久久久久久| 国产视频在线观看免费 | 国产精品1000部啪视频| 精品国产一区探花在线观看| 日韩专区中文字幕| 久久久久久欧美精品se一二三四| 亚洲美女黄色| 国产精品视频成人| 黄色av网址在线| 久久久亚洲午夜电影| 一区二区三区|亚洲午夜| 特级毛片在线| 在线亚洲一区二区| 久久精品无码一区二区三区毛片| 欧美福利在线播放网址导航| 自拍偷拍亚洲一区| 国产无码精品在线观看| 日本免费新一区视频 | 国产96在线亚洲| 亚洲午夜国产成人av电影男同| 无码黑人精品一区二区| 香蕉久久夜色精品国产| 91久久在线播放| 你懂得网站在线| 夜夜揉揉日日人人青青一国产精品| 欧美日韩黄色一级片| 亚洲伦理一区二区| 亚洲欧美国产精品久久久久久久| 国产极品国产极品| 日韩和的一区二区| 黄色99视频| 国产1区在线| 91福利在线播放| 国产精品扒开腿做爽爽爽a片唱戏 亚洲av成人精品一区二区三区 | 欧美性猛xxx| 欧美日韩一区二区区| 精品视频网站| 97国产精品人人爽人人做| 91久久久久国产一区二区| 久久久噜噜噜久久中文字幕色伊伊| 无码日本精品xxxxxxxxx| 成人交换视频| 亚洲男人天堂古典| 黄色小说在线观看视频| 国产美女精品人人做人人爽| 亚洲成人午夜在线| 伊人网在线播放| 日韩欧美在线不卡| 婷婷伊人五月天| 久久国产精品第一页| 欧美日韩大片一区二区三区| aa国产成人| 日韩精品中文字幕一区| 日本黄色小说视频| 久久国产婷婷国产香蕉| 亚洲欧美丝袜| 福利一区视频| 中文欧美日本在线资源| 欧美brazzers| 国产日韩欧美电影| 国模少妇一区二区三区| 久久天天狠狠| a级片免费在线观看| 欧美一区二区三区在线观看 | 99久久综合精品| 成人免费在线网| 成人午夜大片| 久久人人爽人人爽人人片av高请| 精品久久无码中文字幕| 亚洲黄色性网站| 国产日韩精品在线播放| 最近中文字幕一区二区| 亚洲动漫精品| 国产盗摄xxxx视频xxx69| 美国一级片在线免费观看视频| 日韩欧美亚洲综合| 91精品人妻一区二区三区| 手机精品视频在线观看| 日韩视频专区| 日韩美香港a一级毛片| 久久精品国产一区二区三区| 一区二区三区免费在线| 亚洲图片激情小说| 九九热视频免费| 午夜视频精品| 精品国产一区二区三区日日嗨| 色黄视频在线观看| 一区二区三区视频在线| 一区二区三区日| 亚洲一区在线观看免费| 中国美女乱淫免费看视频| 日本怡春院一区二区| 伊人久久大香线蕉午夜av| 日本亚洲视频| 国产91精品青草社区| 成a人v在线播放| 这里只有精品电影| 日本熟妇毛耸耸xxxxxx| 国产女人aaa级久久久级 | 超碰97成人| 久久久99久久精品女同性| 超碰人人人人人人| 欧美日韩中文在线观看| 国产又粗又长又黄的视频| 国产高清一区日本| 免费黄色日本网站| 天天做天天爱天天综合网| 国产精品二区三区| 电影在线观看一区二区| 欧美高清视频在线| 黄视频在线播放| 日韩三级电影网址| 欧美精品亚洲精品日韩精品| 国产精品妹子av| 亚洲啪av永久无码精品放毛片| 日韩福利视频网| 欧美在线观看视频免费| 欧洲福利电影| 国产麻豆乱码精品一区二区三区| 视频一区在线免费看| 久久99精品视频一区97| 成人在线观看免费| 亚洲大胆美女视频| 在线观看中文字幕av| 性做久久久久久久免费看| 欧美88888| 91香蕉视频mp4| 五月天六月丁香| 日韩av一区二区在线影视| 欧美黄网在线观看| 久久视频精品| 农村寡妇一区二区三区| 综合激情网...| 91精品国产自产在线老师啪| 中国色在线日|韩| 欧美精品免费在线观看| www.亚洲.com| 日韩电视剧免费观看网站| 99er热精品视频| 欧美网站一区二区| 亚洲影院在线播放| 亚洲高清免费观看高清完整版在线观看| 九一在线免费观看| 2024国产精品视频| 人妻 日韩 欧美 综合 制服| 国产一区欧美二区| 一区二区三区免费播放| 亚洲一区二区免费看| 成人在线播放网址| 欧美一区二区三区久久精品茉莉花| 亚洲欧美久久久久一区二区三区| 怕怕欧美视频免费大全| 九九九九精品九九九九| 女同一区二区三区| 成人精品水蜜桃| 久久影视精品| 国产免费一区视频观看免费| 国产韩日精品| 国产成人精品优优av| 成人免费网站视频| 欧美一区二区三区……| 白浆在线视频| 97精品在线视频| 韩日毛片在线观看| 97久久国产精品| 国模套图日韩精品一区二区| 欧洲中文字幕国产精品| av高清不卡| 国产精品69久久久久| 少妇一区视频| 国产精品美女久久久久久免费| 欧美国产日韩电影| 91精品久久久久久久久久入口| 日本国产亚洲| 亚洲精品免费一区二区三区| 日本一区二区三区播放| 成人午夜电影在线播放| 日韩av中文字幕一区| 欧美精品中文字幕一区二区| 韩日一区二区三区| 午夜精品区一区二区三| 99热国内精品| 久久久久久av无码免费网站下载| 国语自产精品视频在线看8查询8| 国产va亚洲va在线va| 亚洲一区视频| 天天干在线影院| 精品亚洲porn| 久久综合桃花网| 成人福利视频网站| 变态另类ts人妖一区二区| 国产精品久久午夜| 久久网一区二区| 欧美体内谢she精2性欧美| 青青艹在线观看| 欧美一二三四区在线| 天天干天天操av| 中文字幕亚洲欧美在线| 日本伦理一区二区| 日本一本a高清免费不卡| 福利一区二区| 国产日韩亚洲精品| 成人区精品一区二区婷婷| 黄色影视在线观看| 午夜亚洲性色福利视频| 福利片一区二区三区| 播五月开心婷婷综合| 国产一二三四区在线| 亚洲一区免费视频| 最近日韩免费视频| 精品国产伦一区二区三区免费 | 成人午夜视屏| 91精品视频播放| 国产一区福利| 夜夜春亚洲嫩草影视日日摸夜夜添夜| 黄色综合网站| 天天爽人人爽夜夜爽| 99天天综合性| 黄视频网站免费看| 91黄色免费网站| 三级视频在线看| 日韩中文在线视频| 黄色软件视频在线观看| 成人免费视频在线观看超级碰| 久久综合社区| 麻豆一区二区三区在线观看| 巨乳诱惑日韩免费av| 中文字幕人妻一区| 亚洲欧洲精品天堂一级| 老熟妇仑乱一区二区av| 日韩精品最新网址| 永久免费av在线| 欧美在线免费视频| 99精品国产一区二区三区2021| 亚洲激情一区二区| 国产精品亚洲产品| japan高清日本乱xxxxx| 国产精品欧美久久久久一区二区| 日韩欧美三级在线观看| 欧美一区二区性放荡片| freemovies性欧美| 欧美自拍视频在线观看| 激情小说一区| 激情五月六月婷婷| 精品一区二区免费在线观看| 毛片aaaaaa| 日韩欧美中文字幕在线观看| 欧美自拍第一页| 欧美激情伊人电影| 精品视频在线观看免费观看 | 欧美一级片在线免费观看| 国产精品美女久久久久aⅴ国产馆| 黄色在线免费观看| 日韩精品免费在线视频观看| 91超碰在线播放| 99久久综合狠狠综合久久止| 中文一区一区三区免费在线观看| 97人人爽人人| 国产精品久久久久久久久动漫 | 天堂久久一区二区三区| 精品夜夜澡人妻无码av| 欧美日韩美女在线观看| 天堂网av2014| 97av在线播放| 伊人成综合网yiren22| 免费毛片小视频| 久久综合国产精品| 特级做a爱片免费69| 亚洲免费精彩视频| 全亚洲第一av番号网站| 日韩欧美精品一区二区三区经典 | 日韩一区日韩二区| 91中文字幕在线播放| www国产精品视频| 国产精久久一区二区| 18视频在线观看娇喘| 国产宾馆实践打屁股91| 国产成人啪精品午夜在线观看| 精品999在线播放| 是的av在线| 奇米影视首页 狠狠色丁香婷婷久久综合 | 国产一区二区精彩视频| 日韩一级二级三级精品视频| 国产色婷婷在线| 国产专区一区二区| 久久久久.com| 永久av免费网站| 欧美变态凌虐bdsm| 91精品论坛| 亚洲午夜精品一区二区| 国产精品一区免费在线观看| 国产成年人免费视频| 亚洲人成欧美中文字幕| 久久国内精品| 男人c女人视频| 91欧美激情一区二区三区成人| 中文字幕一区二区人妻视频| 在线播放国产精品| 日韩欧美另类中文字幕| 日韩中文字幕在线视频观看| 国产欧美综合在线观看第十页| 国产女人高潮时对白| 91黄色8090| 欧美好骚综合网| 欧美xxxxx少妇| 在线免费亚洲电影| 日本伦理一区二区| 日本一区二区三区视频免费看| 国产在线精品一区二区夜色 | 涩视频在线观看|