Closed shanerodrigues closed 2 years ago
Maybe, it can, but I haven't learn about jetpack compose.
Ok, thanks for your help.
It's ok!
Yes, it can. I am using it in compose.
@Luke-Tang, thanks for letting me know! I would really appreciate it if you could provide an example of how you did it.
@shanerodrigues The code is roughly as follows, remember grant camera permission.
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
YourAppTheme(darkTheme = true) {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
YourApp()
}
}
}
}
}
@Composable
fun rememberCameraClient(context: Context): CameraClient = remember {
CameraClient.newBuilder(context).apply {
setEnableGLES(true)
setRawImage(false)
setCameraStrategy(CameraUvcStrategy(context))
setCameraRequest(
CameraRequest.Builder()
.setFrontCamera(true)
.setPreviewWidth(960)
.setPreviewHeight(720)
.create()
)
openDebug(true)
}.build()
}
@Composable
fun YourApp() {
val context = LocalContext.current
Box(modifier = Modifier.fillMaxSize()) {
UVCCameraPreview(rememberCameraClient(context))
}
}
@Composable
fun UVCCameraPreview(cameraClient : CameraClient) {
AndroidView(
factory = { ctx ->
AspectRatioSurfaceView(ctx).apply {
this.holder.addCallback(object : Callback {
override fun surfaceCreated(holder: SurfaceHolder) {
cameraClient.openCamera(this@apply)
}
override fun surfaceChanged(
holder: SurfaceHolder,
format: Int,
width: Int,
height: Int
) {
cameraClient.setRenderSize(width, height)
}
override fun surfaceDestroyed(holder: SurfaceHolder) {
cameraClient.closeCamera()
}
})
}
}
) {
}
}
@Luke-Tang, thank you very much for your help. I've got it working perfectly! in case anyone wants a working compose version, here's the link to the repo https://github.com/shanerodrigues/compose-uvc-camera
@Luke-Tang one last question, if you don't mind. I'm not sure how to implement captureImage. I've got this code, any tips on how to do it?
fun YourApp() {
var cClient = rememberCameraClient(LocalContext.current)
val context = LocalContext.current
Box(modifier = Modifier.fillMaxSize()) {
UVCCameraPreview(rememberCameraClient(context))
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Bottom,
horizontalAlignment = Alignment.CenterHorizontally,
){
Button(onClick={clickPhoto(cClient)}){
Text("Take Picture")
}
}
}
}
fun clickPhoto(cameraClient : CameraClient){
Log.i("check", "inside click photo")
ToastUtils.show("inside click photo")
cameraClient?.captureImage(object : ICaptureCallBack {
override fun onBegin() {
ToastUtils.show("OnBegin")
Log.i(TAG, "onBegin")
}
override fun onError(error: String?) {
ToastUtils.show(error ?: "未知异常")
Log.i(TAG, "onError")
}
override fun onComplete(path: String?) {
ToastUtils.show("OnComplete")
Log.i(TAG, "onComplete")
}
})
}
@shanerodrigues Yes, that's correct. You may be pay attention to storage permision, especially target version greater than android10. The build target of this library is 27。
@Luke-Tang would you know how to take a high-resolution photo? In rememberCameraClient I've set the resolution to 2592x1944 which my camera supports, but the photos are taken with the preview width of 800x600. Does it have something to do with the AspectRatioSurfaceView?
compose demo. From 3.2.9
class Test6Activity : ComponentActivity() {
lateinit var client: MultiCameraClient
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
client = MultiCameraClient(this, object : IDeviceConnectCallBack {
override fun onAttachDev(device: UsbDevice?) {
LogUtil.d("onAttachDev >>> $device")
if (device != null) {
LogUtil.d("device.id >>> ${device.productId}")
}
device ?: return
if (mCameraMap.containsKey(device.productId)) {
return
}
CameraUVC(this@Test6Activity, device).apply {
mCameraMap[device.productId] = this
client.requestPermission(device)
}
}
override fun onDetachDec(device: UsbDevice?) {
LogUtil.d("onDetachDec >>> $device")
}
override fun onConnectDev(device: UsbDevice?, ctrlBlock: USBMonitor.UsbControlBlock?) {
LogUtil.d("onConnectDev >>> $device")
mCameraMap[device?.productId]?.apply {
setUsbControlBlock(ctrlBlock)
}
}
override fun onDisConnectDec(
device: UsbDevice?, ctrlBlock: USBMonitor.UsbControlBlock?
) {
LogUtil.d("onDisConnectDec >>> $device")
}
override fun onCancelDev(device: UsbDevice?) {
LogUtil.d("onCancelDev >>> $device")
}
})
client.register()
setContent {
CloudCanteenPlusTheme {
Surface(
modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background
) {
MyApp()
}
}
}
}
private val mCameraMap = hashMapOf<Int, MultiCameraClient.ICamera>()
@Composable
private fun MyApp() {
Box(modifier = Modifier.fillMaxWidth()) {
var device1 by remember {
mutableStateOf<MultiCameraClient.ICamera?>(null)
}
LaunchedEffect(key1 = true, block = {
delay(1000)
device1 = mCameraMap[1002] // 1002 自己的摄像头
})
LogUtil.d("MyApp device1 >>> $device1")
device1?.let {
UVCCameraPreview(
modifier = Modifier.fillMaxSize(),
it
)
}
}
}
@Composable
private fun UVCCameraPreview(
modifier: Modifier = Modifier,
cameraClient: MultiCameraClient.ICamera
) {
Box(
modifier = modifier
.aspectRatio(4f / 3f)
) {
AndroidView(factory = { ctx ->
AspectRatioSurfaceView(ctx).apply {
this.holder.addCallback(object : SurfaceHolder.Callback {
override fun surfaceCreated(holder: SurfaceHolder) {
val request = CameraRequest.Builder()
.setPreviewWidth(640)
.setPreviewHeight(480)
.create()
cameraClient.openCamera(this@apply, request)
cameraClient.addPreviewDataCallBack(object : IPreviewDataCallBack {
override fun onPreviewData(
data: ByteArray?,
width: Int,
height: Int,
format: IPreviewDataCallBack.DataFormat
) {
// data:4915207 width:1280 height:960 format:RGBA
LogUtil.d("onPreviewData >>> data:${data?.size} width:$width height:$height format:$format")
// Receive Data
}
})
}
override fun surfaceChanged(
holder: SurfaceHolder, format: Int, width: Int, height: Int
) {
cameraClient.setRenderSize(width, height)
}
override fun surfaceDestroyed(holder: SurfaceHolder) {
cameraClient.closeCamera()
}
})
}
}) {}
}
}
}
Hello, I'm new to android development. I have a jetpack compose project and want to use AUSBC to use my external camera in the app to take photos. Is it possible to use AUSBC with jetpack compose? If so, can you provide some info on how to do it?