Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
A
Android_Catering_service
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
姜天宇
Android_Catering_service
Commits
ad40cf69
Commit
ad40cf69
authored
Aug 02, 2024
by
姜天宇
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(v1.0.1): 增加Camerax
parent
2e307acd
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
329 additions
and
12 deletions
+329
-12
build.gradle
app/build.gradle
+8
-4
build.gradle
build.gradle
+1
-0
build.gradle
camera/build.gradle
+1
-1
CameraxController.java
...a/src/main/java/com/wmdigit/camera/CameraxController.java
+230
-0
OnImageAnalyzeListener.java
...a/com/wmdigit/camera/listener/OnImageAnalyzeListener.java
+17
-0
CameraFrame.java
...a/src/main/java/com/wmdigit/camera/model/CameraFrame.java
+48
-0
build.gradle
common/build.gradle
+6
-2
history.txt
history.txt
+3
-1
build.gradle
module-demo/build.gradle
+1
-0
DemoHomeFragment.java
...git/cateringdetect/demo/ui/fragment/DemoHomeFragment.java
+14
-4
No files found.
app/build.gradle
View file @
ad40cf69
plugins
{
id
'com.android.application'
id
'org.jetbrains.kotlin.android'
}
android
{
...
...
@@ -10,8 +11,8 @@ android {
applicationId
"com.wmdigit.cateringdetect"
minSdk
24
targetSdk
33
versionCode
1000
0
00
versionName
"1.0.
0
"
versionCode
1000
1
00
versionName
"1.0.
1
"
testInstrumentationRunner
"androidx.test.runner.AndroidJUnitRunner"
...
...
@@ -37,8 +38,11 @@ android {
}
}
compileOptions
{
sourceCompatibility
JavaVersion
.
VERSION_1_8
targetCompatibility
JavaVersion
.
VERSION_1_8
sourceCompatibility
JavaVersion
.
VERSION_17
targetCompatibility
JavaVersion
.
VERSION_17
}
kotlinOptions
{
jvmTarget
=
'17'
}
buildFeatures
{
viewBinding
true
...
...
build.gradle
View file @
ad40cf69
...
...
@@ -2,4 +2,5 @@
plugins
{
id
'com.android.application'
version
'8.1.0-beta01'
apply
false
id
'com.android.library'
version
'8.1.0-beta01'
apply
false
id
'org.jetbrains.kotlin.android'
version
'1.8.0'
apply
false
}
\ No newline at end of file
camera/build.gradle
View file @
ad40cf69
...
...
@@ -33,7 +33,7 @@ dependencies {
implementation
project
(
path:
":common"
)
// CameraX core library using the camera2 implementation
def
camerax_version
=
"1.
4
.0-beta02"
def
camerax_version
=
"1.
2
.0-beta02"
// The following line is optional, as the core library is included indirectly by camera-camera2
implementation
"androidx.camera:camera-core:${camerax_version}"
implementation
"androidx.camera:camera-camera2:${camerax_version}"
...
...
camera/src/main/java/com/wmdigit/camera/CameraxController.java
0 → 100644
View file @
ad40cf69
package
com
.
wmdigit
.
camera
;
import
android.annotation.SuppressLint
;
import
android.content.Context
;
import
android.graphics.Bitmap
;
import
android.util.Size
;
import
androidx.camera.core.Camera
;
import
androidx.camera.core.CameraInfo
;
import
androidx.camera.core.CameraSelector
;
import
androidx.camera.core.ImageAnalysis
;
import
androidx.camera.core.ImageProxy
;
import
androidx.camera.lifecycle.ProcessCameraProvider
;
import
androidx.core.content.ContextCompat
;
import
androidx.lifecycle.LifecycleOwner
;
import
com.elvishew.xlog.XLog
;
import
com.google.common.util.concurrent.ListenableFuture
;
import
com.wmdigit.camera.listener.OnImageAnalyzeListener
;
import
com.wmdigit.common.utils.YuvToRgbConverter
;
import
java.util.List
;
import
java.util.concurrent.ExecutionException
;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.Executors
;
/**
* 相机管理类
* @author dizi
*/
public
class
CameraxController
{
/**
* 摄像头预览分辨率
*/
private
final
Size
CAMERA_PREVIEW_SIZE
=
new
Size
(
640
,
480
);
/**
* 帧处理的时间间隔
*/
private
final
long
INTERVAL_FRAMES_ANALYZE
=
100L
;
private
static
CameraxController
instance
;
private
Context
context
;
/**
* 获取相机服务provider
*/
private
ListenableFuture
<
ProcessCameraProvider
>
cameraProviderFutureListener
;
/**
* 相机的生命周期
*/
private
LifecycleOwner
lifecycleOwner
;
/**
* 图片分析线程
*/
private
final
ExecutorService
executors
=
Executors
.
newFixedThreadPool
(
1
);
/**
* YUV转RGB转化器
*/
private
YuvToRgbConverter
yuvToRgbConverter
;
/**
* 图片分析回调
*/
private
OnImageAnalyzeListener
onImageAnalyzeListener
;
public
static
CameraxController
getInstance
(
Context
context
)
{
if
(
instance
==
null
){
synchronized
(
CameraxController
.
class
){
if
(
instance
==
null
){
instance
=
new
CameraxController
(
context
);
}
}
}
return
instance
;
}
public
static
CameraxController
getInstance
()
{
return
instance
;
}
public
CameraxController
(
Context
context
)
{
this
.
context
=
context
;
this
.
cameraProviderFutureListener
=
ProcessCameraProvider
.
getInstance
(
context
);
this
.
yuvToRgbConverter
=
new
YuvToRgbConverter
(
context
);
}
/**
* 配置生命周期
* @param lifecycleOwner
* @return
*/
public
CameraxController
setLifecycleOwner
(
LifecycleOwner
lifecycleOwner
)
{
this
.
lifecycleOwner
=
lifecycleOwner
;
return
this
;
}
/**
* 注册图片分析回调
* @param onImageAnalyzeListener
* @return
*/
public
CameraxController
setOnImageAnalyzeListener
(
OnImageAnalyzeListener
onImageAnalyzeListener
)
{
this
.
onImageAnalyzeListener
=
onImageAnalyzeListener
;
return
this
;
}
/**
* 相机初始化
*/
public
void
apply
(){
cameraProviderFutureListener
.
addListener
(()
->
{
try
{
// 获取cameraProvider
ProcessCameraProvider
cameraProvider
=
cameraProviderFutureListener
.
get
();
// 创建图像分析器
ImageAnalysis
imageAnalysis
=
createImageAnalysis
();
// 绑定相机
Camera
camera
=
bindCamera
(
cameraProvider
,
imageAnalysis
);
if
(
camera
!=
null
)
{
// 观察相机状态
observeCameraLifecycle
(
camera
);
}
}
catch
(
ExecutionException
|
InterruptedException
e
){
XLog
.
e
(
e
.
toString
());
}
},
ContextCompat
.
getMainExecutor
(
context
));
}
/**
* 创建图片分析器
* @return
*/
private
ImageAnalysis
createImageAnalysis
()
{
// 构建分析器
ImageAnalysis
imageAnalysis
=
new
ImageAnalysis
.
Builder
()
.
setOutputImageFormat
(
ImageAnalysis
.
OUTPUT_IMAGE_FORMAT_YUV_420_888
)
.
setTargetResolution
(
CAMERA_PREVIEW_SIZE
)
// 非阻塞
.
setBackpressureStrategy
(
ImageAnalysis
.
STRATEGY_KEEP_ONLY_LATEST
)
.
build
();
// 实现分析回调
imageAnalysis
.
setAnalyzer
(
executors
,
imageProxy
->{
long
startTime
=
System
.
currentTimeMillis
();
// 处理图片
analyzeImage
(
imageProxy
);
imageProxy
.
close
();
// 休眠
long
costTime
=
System
.
currentTimeMillis
()
-
startTime
;
System
.
out
.
println
(
"处理时间:"
+
costTime
);
long
leftTime
=
INTERVAL_FRAMES_ANALYZE
-
costTime
;
if
(
leftTime
<=
INTERVAL_FRAMES_ANALYZE
&&
leftTime
>=
0
){
try
{
Thread
.
sleep
(
leftTime
);
}
catch
(
InterruptedException
e
)
{
e
.
printStackTrace
();
}
}
});
return
imageAnalysis
;
}
/**
* 处理图像
* @param imageProxy
*/
private
void
analyzeImage
(
ImageProxy
imageProxy
)
{
try
{
// 生成Bitmap
Bitmap
bitmap
=
Bitmap
.
createBitmap
(
imageProxy
.
getWidth
(),
imageProxy
.
getHeight
(),
Bitmap
.
Config
.
ARGB_8888
);
yuvToRgbConverter
.
yuvToRgb
(
imageProxy
.
getImage
(),
bitmap
);
// 回调
if
(
onImageAnalyzeListener
!=
null
){
onImageAnalyzeListener
.
onAnalyzed
(
bitmap
);
}
}
catch
(
Exception
e
){
e
.
printStackTrace
();
}
}
/**
* 绑定相机
* @param cameraProvider
* @param imageAnalysis
*/
private
Camera
bindCamera
(
ProcessCameraProvider
cameraProvider
,
ImageAnalysis
imageAnalysis
)
{
// 防止重复绑定
cameraProvider
.
unbindAll
();
// 获取所有相机
List
<
CameraInfo
>
cameraList
=
cameraProvider
.
getAvailableCameraInfos
();
if
(
cameraList
.
size
()
==
0
){
XLog
.
e
(
"无可用相机!"
);
return
null
;
}
// 相机下标
int
index
=
0
;
if
(
cameraList
.
size
()
>=
2
){
index
=
1
;
}
// 根据下标获取相机
CameraInfo
cameraInfo
=
cameraProvider
.
getAvailableCameraInfos
().
get
(
index
);
@SuppressLint
(
"RestrictedApi"
)
CameraSelector
cameraSelector
=
CameraSelector
.
Builder
.
fromSelector
(
cameraInfo
.
getCameraSelector
())
.
build
();
// 绑定相机、生命周期和图片分析器
return
cameraProvider
.
bindToLifecycle
(
lifecycleOwner
,
cameraSelector
,
imageAnalysis
);
}
/**
* 观察相机生命周期
* @param camera
*/
private
void
observeCameraLifecycle
(
Camera
camera
){
camera
.
getCameraInfo
().
getCameraState
().
removeObservers
(
lifecycleOwner
);
camera
.
getCameraInfo
().
getCameraState
().
observe
(
lifecycleOwner
,
cameraState
->
{
XLog
.
i
(
"相机状态:"
+
cameraState
.
getType
());
switch
(
cameraState
.
getType
()){
case
CLOSED:
// 相机关闭
break
;
default
:
break
;
}
if
(
cameraState
.
getError
()
!=
null
){
XLog
.
i
(
"相机异常:"
+
cameraState
.
getType
());
}
});
}
}
camera/src/main/java/com/wmdigit/camera/listener/OnImageAnalyzeListener.java
0 → 100644
View file @
ad40cf69
package
com
.
wmdigit
.
camera
.
listener
;
import
android.graphics.Bitmap
;
/**
* Camerax的图片回调
* @author dizi
*/
public
interface
OnImageAnalyzeListener
{
/**
* 图片处理完成后,通过此接口回调
* @param bitmap
*/
void
onAnalyzed
(
Bitmap
bitmap
);
}
camera/src/main/java/com/wmdigit/camera/model/CameraFrame.java
0 → 100644
View file @
ad40cf69
package
com
.
wmdigit
.
camera
.
model
;
import
android.graphics.Bitmap
;
import
android.os.Parcel
;
import
android.os.Parcelable
;
/**
* 相机的视频帧
* @author dizi
*/
public
class
CameraFrame
implements
Parcelable
{
private
long
timestamp
;
private
Bitmap
bitmap
;
public
CameraFrame
(
Bitmap
bitmap
)
{
this
.
bitmap
=
bitmap
;
this
.
timestamp
=
System
.
currentTimeMillis
();
}
protected
CameraFrame
(
Parcel
in
)
{
timestamp
=
in
.
readLong
();
bitmap
=
in
.
readParcelable
(
Bitmap
.
class
.
getClassLoader
());
}
@Override
public
void
writeToParcel
(
Parcel
dest
,
int
flags
)
{
dest
.
writeLong
(
timestamp
);
dest
.
writeParcelable
(
bitmap
,
flags
);
}
@Override
public
int
describeContents
()
{
return
0
;
}
public
static
final
Creator
<
CameraFrame
>
CREATOR
=
new
Creator
<
CameraFrame
>()
{
@Override
public
CameraFrame
createFromParcel
(
Parcel
in
)
{
return
new
CameraFrame
(
in
);
}
@Override
public
CameraFrame
[]
newArray
(
int
size
)
{
return
new
CameraFrame
[
size
];
}
};
}
common/build.gradle
View file @
ad40cf69
plugins
{
id
'com.android.library'
id
'org.jetbrains.kotlin.android'
}
android
{
...
...
@@ -26,8 +27,11 @@ android {
}
}
compileOptions
{
sourceCompatibility
JavaVersion
.
VERSION_1_8
targetCompatibility
JavaVersion
.
VERSION_1_8
sourceCompatibility
JavaVersion
.
VERSION_17
targetCompatibility
JavaVersion
.
VERSION_17
}
kotlinOptions
{
jvmTarget
=
'17'
}
buildFeatures
{
...
...
history.txt
View file @
ad40cf69
v1.0.0 2024/07/18 1.演示Demo
\ No newline at end of file
v1.0.0 2024/07/18 1.演示Demo
v1.0.1 2024/08/01 1.增加camerax
2.todo 增加3568视频流算法
\ No newline at end of file
module-demo/build.gradle
View file @
ad40cf69
...
...
@@ -49,6 +49,7 @@ dependencies {
implementation
project
(
path:
":common"
)
implementation
project
(
path:
":core"
)
implementation
project
(
path:
":data-local"
)
implementation
project
(
path:
":camera"
)
implementation
'com.alibaba:arouter-api:1.5.2'
annotationProcessor
'com.alibaba:arouter-compiler:1.5.2'
...
...
module-demo/src/main/java/com/wmdigit/cateringdetect/demo/ui/fragment/DemoHomeFragment.java
View file @
ad40cf69
package
com
.
wmdigit
.
cateringdetect
.
demo
.
ui
.
fragment
;
import
android
x.lifecycle.Observer
;
import
androidx.recyclerview.widget.DiffUtil
;
import
android
.graphics.Bitmap
;
import
androidx.recyclerview.widget.GridLayoutManager
;
import
androidx.recyclerview.widget.LinearLayoutManager
;
import
androidx.recyclerview.widget.RecyclerView
;
import
androidx.recyclerview.widget.SimpleItemAnimator
;
import
com.wmdigit.camera.CameraxController
;
import
com.wmdigit.camera.listener.OnImageAnalyzeListener
;
import
com.wmdigit.cateringdetect.demo.R
;
import
com.wmdigit.cateringdetect.demo.databinding.FragmentDemoHomeBinding
;
import
com.wmdigit.cateringdetect.demo.ui.adapter.DemoImagesAdapter
;
...
...
@@ -80,6 +80,16 @@ public class DemoHomeFragment extends BaseMvvmFragment<DemoHomeViewModel, Fragme
}
});
mDataBinding
.
rvShoppingCart
.
setAdapter
(
shoppingCartAdapter
);
// todo 测试,开相机
CameraxController
.
getInstance
(
requireContext
())
.
setLifecycleOwner
(
this
)
.
setOnImageAnalyzeListener
(
this
::
processBitmap
)
.
apply
();
}
private
void
processBitmap
(
Bitmap
bitmap
){
}
@Override
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment