php拍照从手机相册中选择,Android获取图片:拍照和从相册中选择
概述
在Android開發中獲取圖片主要包括如下兩種方式:
打開相機拍照
從圖庫中選擇圖片
一、打開相機拍照
打開相機拍照主要包括如下幾個部分:
權限申請
打開攝像頭
拍照后傳回數據處理
1. 權限申請
如果需要打開相機,則需要申請攝像頭使用權限,在AndroidManifest.xml文件中添加如下代碼:
如果拍完照片后需要存儲圖片,則還需要文件讀寫的權限.
注意權限申請在Android 6.0以上需要動態申請權限,在此不再贅述。
注意:
Android 10及以上,系統對文件讀寫的控制更加嚴格,如果想要粗暴的實現可讀寫效果,可以在AndroidManifest.xml中下配置如下代碼達到效果:
android:requestLegacyExternalStorage="true"
2. 打開攝像頭
打開攝像頭可以通過設置intent來實現,示例如下:
private fun openCamera() {
if (PermissionUtils.instance.checkPermission(this, Manifest.permission.CAMERA)) {
//為intent指定Action
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
startActivityForResult(intent, IntentUtil.instance.requestCameraPermissionCode)
} else {
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), IntentUtil.instance.requestCameraPermissionCode)
}
}
通過為intent指定攝像頭Action:MediaStore.ACTION_IMAGE_CAPTURE,然后直接通過startActivityForResult的方式啟動Intent即可啟動攝像頭。
3. 拍照后傳回數據處理
在拍照結束后,我們可以對拍照結束后的回傳的intent及攜帶的數據進行處理,例如可以將傳回的圖片以文件的形式保存起來或者直接加載在ImageView中,示例如下:
override fun onActivityResult(requestCode: Int, resultCode: Int, @Nullable data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK) {
when (requestCode) {
IntentUtil.instance.requestCameraPermissionCode -> {
var extra = data?.extras
var photo = extra?.get("data") as Bitmap?
if (photo != null) {
var path = FileUtils.instance.getAppDir()
if (path != null) {
ImageUtils.instance.saveBitmapToFile(photo, System.currentTimeMillis().toString() + ".png",
"TestImg", this)
}
imgQRCode?.setImageBitmap(photo)
}
}
else -> {
}
}
}
}
通過在onActivityResult方法中獲取到了intent對象,從其中獲取到圖片bitmap數據,然后進行對應的圖片操作。
二、從相冊中選取到圖片
從相冊中選取圖片的實現主要包括如下幾個步驟:
權限申請
打開相冊選擇圖片
針對回傳的圖片uri地址去查詢和獲取到對應的文件的真實URI
根據文件URI獲取到圖片
1. 權限申請
從相冊中選取圖片所需要的權限主要包括文件讀權限,在AndroidManifest.xml中添加如下代碼:
Android 6.0及以上需要注意動態權限的申請,在此不再贅述。
Android 10及以上的處理同上。
2. 打開相冊
和打開相機相似,打開相冊也可以通過intent啟動進行打開,示例代碼如下:
private fun openImageUtils() {
val intent: Intent
if (Build.VERSION.SDK_INT < 19) {
intent = Intent(Intent.ACTION_GET_CONTENT)
intent.type = "image/*"
} else {
intent = Intent(
Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
}
startActivityForResult(intent, IntentUtil.instance.openImageGalleryCode)
}
3. 針對回傳數據進行處理
通過startActivityForResult啟動intent,可以在onActivityResult中得到回傳結果,因此可以通過回傳的intent得到選擇的圖片的uri數據,示例代碼如下:
override fun onActivityResult(requestCode: Int, resultCode: Int, @Nullable data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK) {
when (requestCode) {
IntentUtil.instance.openImageGalleryCode -> {
var uri = data?.data
if (data != null && uri != null) {
var imgPath = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
ImageUtils.instance.handleImageBeforeKitKat(data, this)
} else {
ImageUtils.instance.handleImageOnKitKat(data, this)
}
displayImage(imgPath)
}
}
else -> {
}
}
}
}
獲取到URI之后便可以對URI進行處理并獲取到圖片,但是需要注意的是Android在4.4前后通過圖庫選擇得到的圖片的URI并不是一致的,因此需要分開處理。
Android在4.4之前獲取到的URI是真實文件路徑,因此不需要做過多的處理。
Android在4.4之后獲取到URI并不是文件的真實路徑,可能是類似于下面這種路徑,因此需要重新對此URI進行解析以拿到真正的文件路徑。
com.android.providers.media.documents.image%3A11111
解析代碼示例如下:
/**
* 從相冊中讀取圖片,在4.4之后
* @param data:打開圖片選擇后返回的intent
* @param context
* @return
*/
fun handleImageOnKitKat(data: Intent, context: Context?): String? {
var imagePath: String? = null
val uri = data.data
if (DocumentsContract.isDocumentUri(context, uri)) {
// 如果是document類型的Uri,則通過document id處理
val docId = DocumentsContract.getDocumentId(uri)
if ("com.android.providers.media.documents" == uri!!.authority) {
val id = docId.split(":").toTypedArray()[1] // 解析出數字格式的id
val selection = MediaStore.Images.Media._ID + "=" + id
LogUtils.instance.getLogPrint("id=$id,selection=$selection")
imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection, context)
} else if ("com.android.providers.downloads.documents" == uri.authority) {
val contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), java.lang.Long.valueOf(docId))
imagePath = getImagePath(contentUri, null, context)
}
} else if ("content".equals(uri!!.scheme, ignoreCase = true)) {
// 如果是content類型的Uri,則使用普通方式處理
imagePath = getImagePath(uri, null, context)
} else if ("file".equals(uri.scheme, ignoreCase = true)) {
// 如果是file類型的Uri,直接獲取圖片路徑即可
imagePath = uri.path
}
return imagePath
}
/**
* 4.4版本以前,直接獲取真實路徑
* @param data
* @return
*/
fun handleImageBeforeKitKat(data: Intent, context: Context?): String? {
val uri = data.data
return getImagePath(uri, null, context)
}
/**
* 查詢圖庫中是否存在有指定路徑的圖片
* @param uri:路徑URI
* @param selection:篩選條件
* @param context
* @return
*/
private fun getImagePath(uri: Uri?, selection: String?, context: Context?): String? {
var path: String? = null
// 通過Uri和selection來獲取真實的圖片路徑
val cursor: Cursor? = context?.contentResolver?.query(uri!!, null, selection, null, null)
if (cursor != null) {
LogUtils.instance.getLogPrint("cursor不為null $selection")
var i = 0
while (i < cursor.columnCount) {
var ss = cursor.getColumnName(i)
LogUtils.instance.getLogPrint("$i $ss")
i++
}
if (cursor.moveToFirst()) {
path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA))
LogUtils.instance.getLogPrint("get path= $path")
}
cursor.close()
}
return path
}
最終通過cursor進行查詢并獲取到具體的圖片文件地址。
4. 獲取圖片并處理
經過上步之后,我們可以獲取到對應圖片文件地址,可以通過過文件操作獲取文件并添加到ImageView等操作,示例如下:
private fun displayImage(imgPath: String?) {
if (imgPath != null && FileUtils.instance.isFileExist(imgPath)) {
var bitmap = BitmapFactory.decodeFile(imgPath)
imgQRCode?.setImageBitmap(bitmap)
}
}
總結
獲取圖片的兩種方式在實現上有相似的思路,都是經過如下幾步:
申請權限
設置對應的intent Action,通過intent跳轉到對應界面
在ActivityResults中處理返回的數據結果,獲取到b圖片對象。
需要主要的內容包括如下幾點:
權限申請需要注意6.0以上的權限申請以及Android 10以上對于文件讀寫的控制。
打開圖庫選取照片要注意你當前從intent中獲取的uri的格式,不僅僅需要考慮Android sdk版本的不同,同時對于不同的手機機型也有可能返回不同的uri路徑,因此存在有單獨適配的情況。
備注:
總結
以上是生活随笔為你收集整理的php拍照从手机相册中选择,Android获取图片:拍照和从相册中选择的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php 变量写入数据库,PHP基础/JS
- 下一篇: php设置背景为透明,css如何设置背景