Android圖片處理:識別圖像方向并顯示實例教程
更新時間:2013年06月16日 16:38:58 作者:
在Android中使用ImageView顯示圖片的時候發(fā)現(xiàn)圖片顯示不正,方向偏了或者倒過來了,下面與大家分享下具體的解決方法,感性的朋友可以參考下
在Android中使用ImageView顯示圖片的時候發(fā)現(xiàn)圖片顯示不正,方向偏了或者倒過來了。
解決這個問題很自然想到的分兩步走:
1、自動識別圖像方向,計算旋轉(zhuǎn)角度;
2、對圖像進行旋轉(zhuǎn)并顯示。
一、識別圖像方向
首先在這里提一個概念EXIF(Exchangeable Image File Format,可交換圖像文件),具體解釋參見Wiki。
簡而言之,Exif是一個標(biāo)準(zhǔn),用于電子照相機(也包括手機、掃描器等)上,用來規(guī)范圖片、聲音、視屏以及它們的一些輔助標(biāo)記格式。
Exif支持的格式如下:
圖像
壓縮圖像文件:JPEG、DCT
非壓縮圖像文件:TIFF
不支持:JPEG 2000、PNG、GIF
音頻
RIFF、WAV
Android提供了對JPEG格式圖像Exif接口支持,可以讀取JPEG文件metadata信息,參見ExifInterface.
這些Metadata信息總的來說大致分為三類:日期時間、空間信息(經(jīng)緯度、高度)、Camera信息(孔徑、焦距、旋轉(zhuǎn)角、曝光量等等)。
二、圖像旋轉(zhuǎn)
Android中提供了對Bitmap進行矩陣旋轉(zhuǎn)的操作,參見Bitmap提供的靜態(tài)createBitmap方法.
public static Bitmap createBitmap (Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter)

IllegalArgumentException if the x, y, width, height values are outside of the dimensions of the source bitmap.
到此這兩個問題理論上都解決了,開始實際操作一下吧,參照以下代碼。
public class IOHelper {
......
/** 從給定路徑加載圖片*/
public static Bitmap loadBitmap(String imgpath) {
return BitmapFactory.decodeFile(imgpath);
}
/** 從給定的路徑加載圖片,并指定是否自動旋轉(zhuǎn)方向*/
public static Bitmap loadBitmap(String imgpath, boolean adjustOritation) {
if (!adjustOritation) {
return loadBitmap(imgpath);
} else {
Bitmap bm = loadBitmap(imgpath);
int digree = 0;
ExifInterface exif = null;
try {
exif = new ExifInterface(imgpath);
} catch (IOException e) {
e.printStackTrace();
exif = null;
}
if (exif != null) {
// 讀取圖片中相機方向信息
int ori = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_UNDEFINED);
// 計算旋轉(zhuǎn)角度
switch (ori) {
case ExifInterface.ORIENTATION_ROTATE_90:
digree = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
digree = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
digree = 270;
break;
default:
digree = 0;
break;
}
}
if (digree != 0) {
// 旋轉(zhuǎn)圖片
Matrix m = new Matrix();
m.postRotate(digree);
bm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(),
bm.getHeight(), m, true);
}
return bm;
}
}
......
}
解決這個問題很自然想到的分兩步走:
1、自動識別圖像方向,計算旋轉(zhuǎn)角度;
2、對圖像進行旋轉(zhuǎn)并顯示。
一、識別圖像方向
首先在這里提一個概念EXIF(Exchangeable Image File Format,可交換圖像文件),具體解釋參見Wiki。
簡而言之,Exif是一個標(biāo)準(zhǔn),用于電子照相機(也包括手機、掃描器等)上,用來規(guī)范圖片、聲音、視屏以及它們的一些輔助標(biāo)記格式。
Exif支持的格式如下:
圖像
壓縮圖像文件:JPEG、DCT
非壓縮圖像文件:TIFF
不支持:JPEG 2000、PNG、GIF
音頻
RIFF、WAV
Android提供了對JPEG格式圖像Exif接口支持,可以讀取JPEG文件metadata信息,參見ExifInterface.
這些Metadata信息總的來說大致分為三類:日期時間、空間信息(經(jīng)緯度、高度)、Camera信息(孔徑、焦距、旋轉(zhuǎn)角、曝光量等等)。
二、圖像旋轉(zhuǎn)
Android中提供了對Bitmap進行矩陣旋轉(zhuǎn)的操作,參見Bitmap提供的靜態(tài)createBitmap方法.
public static Bitmap createBitmap (Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter)

IllegalArgumentException if the x, y, width, height values are outside of the dimensions of the source bitmap.
到此這兩個問題理論上都解決了,開始實際操作一下吧,參照以下代碼。
復(fù)制代碼 代碼如下:
public class IOHelper {
......
/** 從給定路徑加載圖片*/
public static Bitmap loadBitmap(String imgpath) {
return BitmapFactory.decodeFile(imgpath);
}
/** 從給定的路徑加載圖片,并指定是否自動旋轉(zhuǎn)方向*/
public static Bitmap loadBitmap(String imgpath, boolean adjustOritation) {
if (!adjustOritation) {
return loadBitmap(imgpath);
} else {
Bitmap bm = loadBitmap(imgpath);
int digree = 0;
ExifInterface exif = null;
try {
exif = new ExifInterface(imgpath);
} catch (IOException e) {
e.printStackTrace();
exif = null;
}
if (exif != null) {
// 讀取圖片中相機方向信息
int ori = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_UNDEFINED);
// 計算旋轉(zhuǎn)角度
switch (ori) {
case ExifInterface.ORIENTATION_ROTATE_90:
digree = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
digree = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
digree = 270;
break;
default:
digree = 0;
break;
}
}
if (digree != 0) {
// 旋轉(zhuǎn)圖片
Matrix m = new Matrix();
m.postRotate(digree);
bm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(),
bm.getHeight(), m, true);
}
return bm;
}
}
......
}
相關(guān)文章
Android 使用AlarmManager和NotificationManager來實現(xiàn)鬧鐘和通知欄
這篇文章主要介紹了Android 使用AlarmManager和NotificationManager來實現(xiàn)鬧鐘和通知欄,需要的朋友可以參考下2017-02-02Android編程實現(xiàn)設(shè)置TabHost當(dāng)中字體的方法
這篇文章主要介紹了Android編程實現(xiàn)設(shè)置TabHost當(dāng)中字體的方法,涉及Android針對TabHost屬性操作的相關(guān)技巧,非常簡單實用,需要的朋友可以參考下2015-12-12解決Android Studio 格式化快捷鍵和QQ 鎖鍵盤快捷鍵沖突問題
每次打開qq使用android studio格式化的快捷鍵Ctrl + Alt +L時,總是出現(xiàn)qq鎖鍵盤提示,怎么回事呢?下面小編給大家?guī)砹薬ndroid studio格式化的快捷鍵和qq快捷鍵之間的沖突的處理方法,需要的朋友參考下吧2017-12-12Android 實現(xiàn)帶進度條的WebView的實例
這篇文章主要介紹了Android 實現(xiàn)帶進度條的WebView的實例的相關(guān)資料,這里介紹了Webview加載網(wǎng)頁的方法及帶進度的Drawable文件view_progress_webview的實現(xiàn),需要的朋友可以參考下2017-07-07Android UI設(shè)計系列之自定義Dialog實現(xiàn)各種風(fēng)格的對話框效果(7)
這篇文章主要介紹了Android UI設(shè)計系列之自定義Dialog實現(xiàn)各種風(fēng)格的對話框效果,具有一定的實用性和參考價值,感興趣的小伙伴們可以參考一下2016-06-06Android開發(fā)案例手冊Application跳出dialog
這篇文章主要為大家介紹了Android開發(fā)案例手冊Application跳出dialog,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-06-06Android編程之SQLite數(shù)據(jù)庫操作方法詳解
這篇文章主要介紹了Android編程之SQLite數(shù)據(jù)庫操作方法,簡單介紹了SQLite數(shù)據(jù)庫及Android操作SQLite數(shù)據(jù)庫的步驟與相關(guān)實現(xiàn)技巧,需要的朋友可以參考下2017-08-08