Android圖片處理:識(shí)別圖像方向并顯示實(shí)例教程
更新時(shí)間:2013年06月16日 16:38:58 作者:
在Android中使用ImageView顯示圖片的時(shí)候發(fā)現(xiàn)圖片顯示不正,方向偏了或者倒過來了,下面與大家分享下具體的解決方法,感性的朋友可以參考下
在Android中使用ImageView顯示圖片的時(shí)候發(fā)現(xiàn)圖片顯示不正,方向偏了或者倒過來了。
解決這個(gè)問題很自然想到的分兩步走:
1、自動(dòng)識(shí)別圖像方向,計(jì)算旋轉(zhuǎn)角度;
2、對(duì)圖像進(jìn)行旋轉(zhuǎn)并顯示。
一、識(shí)別圖像方向
首先在這里提一個(gè)概念EXIF(Exchangeable Image File Format,可交換圖像文件),具體解釋參見Wiki。
簡而言之,Exif是一個(gè)標(biāo)準(zhǔn),用于電子照相機(jī)(也包括手機(jī)、掃描器等)上,用來規(guī)范圖片、聲音、視屏以及它們的一些輔助標(biāo)記格式。
Exif支持的格式如下:
圖像
壓縮圖像文件:JPEG、DCT
非壓縮圖像文件:TIFF
不支持:JPEG 2000、PNG、GIF
音頻
RIFF、WAV
Android提供了對(duì)JPEG格式圖像Exif接口支持,可以讀取JPEG文件metadata信息,參見ExifInterface.
這些Metadata信息總的來說大致分為三類:日期時(shí)間、空間信息(經(jīng)緯度、高度)、Camera信息(孔徑、焦距、旋轉(zhuǎn)角、曝光量等等)。
二、圖像旋轉(zhuǎn)
Android中提供了對(duì)Bitmap進(jìn)行矩陣旋轉(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.
到此這兩個(gè)問題理論上都解決了,開始實(shí)際操作一下吧,參照以下代碼。
public class IOHelper {
......
/** 從給定路徑加載圖片*/
public static Bitmap loadBitmap(String imgpath) {
return BitmapFactory.decodeFile(imgpath);
}
/** 從給定的路徑加載圖片,并指定是否自動(dòng)旋轉(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) {
// 讀取圖片中相機(jī)方向信息
int ori = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_UNDEFINED);
// 計(jì)算旋轉(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;
}
}
......
}
解決這個(gè)問題很自然想到的分兩步走:
1、自動(dòng)識(shí)別圖像方向,計(jì)算旋轉(zhuǎn)角度;
2、對(duì)圖像進(jìn)行旋轉(zhuǎn)并顯示。
一、識(shí)別圖像方向
首先在這里提一個(gè)概念EXIF(Exchangeable Image File Format,可交換圖像文件),具體解釋參見Wiki。
簡而言之,Exif是一個(gè)標(biāo)準(zhǔn),用于電子照相機(jī)(也包括手機(jī)、掃描器等)上,用來規(guī)范圖片、聲音、視屏以及它們的一些輔助標(biāo)記格式。
Exif支持的格式如下:
圖像
壓縮圖像文件:JPEG、DCT
非壓縮圖像文件:TIFF
不支持:JPEG 2000、PNG、GIF
音頻
RIFF、WAV
Android提供了對(duì)JPEG格式圖像Exif接口支持,可以讀取JPEG文件metadata信息,參見ExifInterface.
這些Metadata信息總的來說大致分為三類:日期時(shí)間、空間信息(經(jīng)緯度、高度)、Camera信息(孔徑、焦距、旋轉(zhuǎn)角、曝光量等等)。
二、圖像旋轉(zhuǎn)
Android中提供了對(duì)Bitmap進(jìn)行矩陣旋轉(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.
到此這兩個(gè)問題理論上都解決了,開始實(shí)際操作一下吧,參照以下代碼。
復(fù)制代碼 代碼如下:
public class IOHelper {
......
/** 從給定路徑加載圖片*/
public static Bitmap loadBitmap(String imgpath) {
return BitmapFactory.decodeFile(imgpath);
}
/** 從給定的路徑加載圖片,并指定是否自動(dòng)旋轉(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) {
// 讀取圖片中相機(jī)方向信息
int ori = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_UNDEFINED);
// 計(jì)算旋轉(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)文章
超精準(zhǔn)的Android手機(jī)計(jì)步器開發(fā)
這篇文章主要為大家詳細(xì)介紹了超精準(zhǔn)的Android手機(jī)計(jì)步器開發(fā)過程,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
2016-10-10
Android自定義View實(shí)現(xiàn)天氣預(yù)報(bào)折線圖
這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)天氣預(yù)報(bào)折線圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
2022-09-09
Android自定義WheelView地區(qū)選擇三級(jí)聯(lián)動(dòng)
這篇文章主要為大家詳細(xì)介紹了Android自定義WheelView地區(qū)選擇三級(jí)聯(lián)動(dòng)的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
2017-02-02
Android 中ListView的Item點(diǎn)擊事件失效的快速解決方法
這篇文章主要介紹了Android 中ListView的Item點(diǎn)擊事件失效的快速解決方法的相關(guān)資料,需要的朋友可以參考下
2016-09-09
去掉RecycleView或者ListView上下滑動(dòng)陰影的方法
下面小編就為大家分享一篇去掉RecycleView或者ListView上下滑動(dòng)陰影的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
2018-01-01
Android ViewPager與radiogroup實(shí)現(xiàn)關(guān)聯(lián)示例
本篇文章主要介紹了Android ViewPager與radiogroup實(shí)現(xiàn)關(guān)聯(lián)示例,具有一定的參考價(jià)值,有興趣的可以了解一下。
2017-03-03
Android下SDL2實(shí)現(xiàn)五子棋游戲
這篇文章主要為大家詳細(xì)介紹了Android下SDL2實(shí)現(xiàn)五子棋游戲的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
2016-02-02 
