package cn.flightfeather.thirdappmodule.module.common
|
|
import android.annotation.SuppressLint
|
import android.app.Activity
|
import android.content.Intent
|
import android.graphics.Bitmap
|
import android.graphics.BitmapFactory
|
import android.graphics.Canvas
|
import android.graphics.Matrix
|
import android.media.ExifInterface
|
import android.os.Bundle
|
import android.os.Environment
|
import android.os.Environment.DIRECTORY_PICTURES
|
import android.view.View
|
import cn.flightfeather.thirdappmodule.R
|
import cn.flightfeather.thirdappmodule.activity.PhotoViewerActivity
|
import cn.flightfeather.thirdappmodule.module.base.BaseActivity
|
import cn.flightfeather.thirdappmodule.module.base.VIEW_PHOTO
|
import cn.flightfeather.thirdappmodule.util.*
|
import cn.flightfeather.thirdappmodule.util.location.LocationUtil
|
import cn.flightfeather.thirdappmodule.util.photo.ExifHelper
|
import cn.flightfeather.thirdappmodule.util.photo.ImageMergeUtil
|
import com.lcw.library.imagepicker.ImagePicker
|
import com.otaliastudios.cameraview.CameraListener
|
import com.otaliastudios.cameraview.CameraOptions
|
import com.otaliastudios.cameraview.Size
|
import io.reactivex.Observable
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
import io.reactivex.schedulers.Schedulers
|
import kotlinx.android.synthetic.main.activity_camera.*
|
import java.io.File
|
import java.io.FileOutputStream
|
import java.io.Serializable
|
import java.util.*
|
import kotlin.collections.ArrayList
|
import kotlin.math.abs
|
import kotlin.math.round
|
|
/**
|
*
|
*/
|
class CameraActivity : BaseActivity(), View.OnClickListener {
|
|
// gps定位工具
|
private lateinit var locationUtil: LocationUtil
|
|
// 图片文本合并工具
|
private lateinit var imageMergeUtil: ImageMergeUtil
|
|
// 拍摄图片缓存地址
|
private var photoPath = mutableListOf<String>()
|
|
// 图片水印
|
private lateinit var logo: Bitmap
|
|
// 允许最大图片拍摄数量
|
private var maxPic = 3
|
|
override fun getLayoutId(): Int = R.layout.activity_camera
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
super.onCreate(savedInstanceState)
|
initLogoBitmap()
|
initCamera()
|
initLocation()
|
img_cancel.setOnClickListener(this)
|
img_confirm.setOnClickListener(this)
|
img_thumbnail.setOnClickListener(this)
|
// toggle(false)
|
|
maxPic = intent.getIntExtra("maxPic", 3)
|
|
onShootDone()
|
}
|
|
override fun onResume() {
|
super.onResume()
|
camera_view.start()
|
}
|
|
override fun onPause() {
|
super.onPause()
|
camera_view.stop()
|
}
|
|
override fun onDestroy() {
|
super.onDestroy()
|
camera_view.destroy()
|
locationUtil.onDestroy()
|
}
|
|
private fun toggle(isShot: Boolean = true) {
|
if (isShot) {
|
cl_part1.visibility = View.GONE
|
cl_part2.visibility = View.VISIBLE
|
} else {
|
cl_part1.visibility = View.VISIBLE
|
cl_part2.visibility = View.GONE
|
}
|
}
|
|
private fun initLogoBitmap() {
|
logo = BitmapFactory.decodeResource(resources, R.mipmap.ic_logo)
|
}
|
|
private fun initCamera() {
|
imageMergeUtil = ImageMergeUtil(this)
|
|
// 根据系统提供的可选分辨率,选择和当前显示区域最接近的
|
camera_view.setPictureSize{
|
var min = -1//当前分辨率与最小分辨率的长宽分别对应的差值的和
|
|
// val screenWith = ScreenUtils.getScreenWidth(this)
|
// val screenHeight = ScreenUtils.getScreenHeight(this)
|
|
val screenWith = camera_view.width
|
val screenHeight = camera_view.height
|
|
val resultList = mutableListOf<Size>()
|
|
it.forEach {size ->
|
if (size.width > screenWith) return@forEach
|
|
val w = abs(size.width - screenWith)
|
val h = abs(size.height - screenHeight)
|
if (min < 0) {
|
min = w + h
|
resultList.add(0, size)
|
}else if (w + h < min) {
|
min = w + h
|
resultList.add(0, size)
|
}
|
}
|
resultList
|
}
|
camera_view.addCameraListener(object : CameraListener() {
|
override fun onCameraOpened(options: CameraOptions) {
|
super.onCameraOpened(options)
|
btn_shoot.setOnClickListener(this@CameraActivity)
|
}
|
|
|
override fun onPictureTaken(jpeg: ByteArray?) {
|
super.onPictureTaken(jpeg)
|
camera_view.stop()
|
jpeg?.let {
|
toBitmap(it)?.let {b->
|
merge(b)
|
}
|
}
|
}
|
|
override fun onCameraClosed() {
|
super.onCameraClosed()
|
}
|
})
|
}
|
|
@SuppressLint("SetTextI18n")
|
private fun initLocation() {
|
locationUtil = LocationUtil(this)
|
locationUtil.startLocation {
|
val date = Date()
|
val time = DateFormatter.dateTimeFormat3.format(date)
|
runOnUiThread {
|
txt_latitude.text = "经度: ${round(it.longitude * 1000000) / 1000000}"
|
txt_longitude.text = "纬度: ${round(it.latitude * 1000000) / 1000000}"
|
txt_address.text = "地址: ${it.address}"
|
txt_time.text = "时间: $time"
|
}
|
}
|
}
|
|
private fun merge(b: Bitmap) {
|
val d = Observable.create<Bitmap> { emitter ->
|
var newB: Bitmap
|
val width = camera_view.width
|
val height = camera_view.height
|
|
var x = txt_latitude.x - camera_view.x
|
var y = txt_latitude.y - camera_view.y
|
var xScale = x / width
|
var yScale = y / height
|
newB = imageMergeUtil.mergeText(b, txt_latitude, Pair(x, y), xScale, yScale)
|
|
x = txt_longitude.x - camera_view.x
|
y = txt_longitude.y - camera_view.y
|
xScale = x / width
|
yScale = y / height
|
newB = imageMergeUtil.mergeText(newB, txt_longitude, Pair(x, y), xScale, yScale)
|
|
x = txt_address.x - camera_view.x
|
y = txt_address.y - camera_view.y
|
xScale = x / width
|
yScale = y / height
|
newB = imageMergeUtil.mergeText(newB, txt_address, Pair(x, y), xScale, yScale)
|
|
x = txt_time.x - camera_view.x
|
y = txt_time.y - camera_view.y
|
xScale = x / width
|
yScale = y / height
|
newB = imageMergeUtil.mergeText(newB, txt_time, Pair(x, y), xScale, yScale)
|
|
newB = imageMergeUtil.addLogo(newB, logo)
|
|
// 缓存图片
|
val path = Environment.getExternalStorageDirectory().path + "/FlightFeather/Temp/" + UUIDGenerator.generateUUID(4) + ".jpg"
|
photoPath.add(path)
|
SystemServiceUtils.saveBitmap(path, newB)
|
|
emitter.onNext(newB)
|
emitter.onComplete()
|
}.subscribeOn(Schedulers.io())
|
.observeOn(AndroidSchedulers.mainThread())
|
.subscribe {
|
// toggle(true)
|
|
// 拍摄loading结束
|
onShootDone()
|
|
// 在缩略图上显示最新一张图片, 并更新确认按钮文字显示
|
img_thumbnail.setImageBitmap(it)
|
val t = "${getString(R.string.yes)}(${photoPath.size}/${maxPic})"
|
img_confirm.text = t
|
// 判断是否达到允许最大图片数量
|
if (photoPath.size == maxPic) {
|
// 弹出提示框,确认或者重拍
|
DialogUtil2.showAlertDialog2(this, "最多拍${maxPic}张照片", getString(R.string.yes), getString(R.string.reshoot), { d ->
|
d.dismiss()
|
onConfirm()
|
}, { d ->
|
d.dismiss()
|
onCancel()
|
camera_view.start()
|
})
|
} else {
|
camera_view.start()
|
}
|
}
|
disposableList.add(d)
|
}
|
|
private fun toBitmap(source: ByteArray): Bitmap? {
|
var orientation: Int
|
var flip: Boolean
|
var outputStream: FileOutputStream? = null
|
|
try {
|
val file = File(getExternalFilesDir(DIRECTORY_PICTURES), "IMG_${Date().time}.jpeg")
|
outputStream = FileOutputStream(file)
|
outputStream.write(source)
|
val exif = ExifInterface(file.absolutePath)
|
val exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
|
ExifInterface.ORIENTATION_NORMAL)
|
orientation = ExifHelper.getOrientation(exifOrientation)
|
flip = exifOrientation == ExifInterface.ORIENTATION_FLIP_HORIZONTAL ||
|
exifOrientation == ExifInterface.ORIENTATION_FLIP_VERTICAL ||
|
exifOrientation == ExifInterface.ORIENTATION_TRANSPOSE ||
|
exifOrientation == ExifInterface.ORIENTATION_TRANSVERSE
|
} catch (e: Exception) {
|
e.printStackTrace()
|
orientation = 0
|
flip = false
|
} finally {
|
outputStream?.flush()
|
outputStream?.close()
|
}
|
|
var bitmap: Bitmap?
|
try {
|
bitmap = BitmapFactory.decodeByteArray(source, 0, source.size)
|
if (orientation != 0 || flip) {
|
val matrix = Matrix()
|
matrix.setRotate(orientation.toFloat())
|
val temp = bitmap
|
bitmap = Bitmap.createBitmap(bitmap!!, 0, 0, bitmap.width,
|
bitmap.height, matrix, true)
|
temp!!.recycle()
|
}
|
} catch (e: OutOfMemoryError) {
|
bitmap = null
|
}
|
return bitmap
|
}
|
|
/**
|
* 确认返回
|
*/
|
private fun onConfirm() {
|
if (photoPath.isEmpty()) return
|
val intent = Intent()
|
intent.putStringArrayListExtra(ImagePicker.EXTRA_SELECT_IMAGES, ArrayList(photoPath))
|
setResult(Activity.RESULT_OK, intent)
|
this.finish()
|
}
|
|
/**
|
* 取消拍摄
|
*/
|
private fun onCancel() {
|
photoPath.forEach {
|
val pic = File(it)
|
if (pic.exists()) pic.delete()
|
}
|
photoPath.clear()
|
img_thumbnail.setImageResource(R.drawable.bg_btngroup)
|
img_confirm.text = getString(R.string.yes)
|
}
|
|
/**
|
* 照片拍摄处理中
|
*/
|
private fun onShooting() {
|
pro_shooting.visibility = View.VISIBLE
|
btn_shoot.isEnabled = false
|
}
|
|
/**
|
* 照片拍摄处理完毕
|
*/
|
private fun onShootDone() {
|
pro_shooting.visibility = View.GONE
|
btn_shoot.isEnabled = true
|
}
|
|
override fun onBackPressed() {
|
onCancel()
|
super.onBackPressed()
|
}
|
|
override fun onClick(v: View?) {
|
when (v?.id) {
|
R.id.btn_shoot -> {
|
onShooting()
|
camera_view.capturePicture()
|
// capture()
|
}
|
// 取消拍摄的图片并回退
|
R.id.img_cancel -> {
|
onBackPressed()
|
}
|
//
|
R.id.img_confirm -> onConfirm()
|
R.id.img_thumbnail -> {
|
if (photoPath.isEmpty()) return
|
val fileList = mutableListOf<File>()
|
photoPath.forEach { fileList.add(File(it)) }
|
val intent = Intent(this, PhotoViewerActivity::class.java)
|
intent.putExtra("position", fileList.size - 1)
|
intent.putExtra("type", PhotoViewerActivity.EVIDENCE_PHOTO_TEMP)
|
intent.putExtra("deletable", false)
|
intent.putExtra(PhotoViewerActivity.PARA_FILES, fileList as Serializable)
|
startActivityForResult(intent, VIEW_PHOTO)
|
}
|
}
|
}
|
}
|