การถ่ายภาพ
บันทึกและจัดเก็บรูปภาพ
การถ่ายภาพ เป็นบทเรียน Android Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Android Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Android Academy มีบทเรียนทั้งหมด 4 บทเรียน
การถ่ายภาพ
เมื่อมีภาพตัวอย่างบนหน้าจอแล้ว ขั้นตอนถัดไปคือ ถ่ายภาพ CameRX จัดการเรื่องนี้ด้วยกรณีการใช้งาน ImageCapture
คุณจะเชื่อม ImageCapture ไว้พร้อมกับภาพตัวอย่าง จากนั้นเรียก takePicture() เมื่อผู้ใช้แตะปุ่มชัตเตอร์ และบันทึกผลลัพธ์ลงแกลเลอรีของอุปกรณ์
การสร้างกรณีการใช้งาน ImageCapture
ImageCapture กำหนดค่าด้วย builder ตัวเลือกที่มีประโยชน์คือ โหมดการถ่ายภาพ ซึ่งเป็นการแลกเปลี่ยนระหว่างเวลาแฝงกับคุณภาพ:
CAPTURE_MODE_MINIMIZE_LATENCY— ชัตเตอร์ทำงานเร็วCAPTURE_MODE_MAXIMIZE_QUALITY— ภาพมีคุณภาพดีที่สุดแต่ช้าลงเล็กน้อย
val imageCapture = ImageCapture.Builder()
.setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
.build()การเชื่อม Preview + ImageCapture
คุณสามารถเชื่อมกรณีการใช้งานหลายรายการพร้อมกันได้ ส่งทั้ง preview และ imageCapture ไปยัง bindToLifecycle เพื่อให้กล้องแสดงภาพสดและพร้อมถ่ายภาพ
cameraProvider.unbindAll()
cameraProvider.bindToLifecycle(
lifecycleOwner,
CameraSelector.DEFAULT_BACK_CAMERA,
preview,
imageCapture
)จะบันทึกที่ใด: MediaStore
วิธีสมัยใหม่ที่ทำงานได้ดีกับพื้นที่จัดเก็บแบบกำหนดขอบเขตในการบันทึกภาพคือใช้ MediaStore คุณอธิบายไฟล์ (ชื่อ ประเภท MIME โฟลเดอร์) ด้วย ContentValues แล้วให้ระบบจัดเก็บลงในคอลเลกชัน Pictures ที่ใช้ร่วมกัน
วิธีนี้ทำงานได้โดยไม่ต้องใช้สิทธิ์แบบเดิม WRITE_EXTERNAL_STORAGE บน Android 10 ขึ้นไป
val name = "photo_${System.currentTimeMillis()}"
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, name)
put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/MyApp")
}ตัวเลือกเอาต์พุต
หากต้องการบอก CameraX ว่าจะเขียนไฟล์ JPEG ที่ใด ให้สร้าง OutputFileOptions จากตัวแก้ไขเนื้อหา URI ของคอลเลกชันเป้าหมาย และ ContentValues ของคุณ
val outputOptions = ImageCapture.OutputFileOptions
.Builder(
context.contentResolver,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
contentValues
)
.build()การเรียก takePicture()
ถึงเวลาสั่งถ่ายภาพแล้ว takePicture() รับตัวเลือกเอาต์พุต Executor และการเรียกกลับ CameRX จะรายงานความสำเร็จหรือข้อผิดพลาดแบบอะซิงโครนัส
ใช้ ContextCompat.getMainExecutor(context) เพื่อให้การเรียกกลับทำงานบนเธรดหลัก
imageCapture.takePicture(
outputOptions,
ContextCompat.getMainExecutor(context),
object : ImageCapture.OnImageSavedCallback {
override fun onImageSaved(output: ImageCapture.OutputFileResults) {
val savedUri = output.savedUri
// Photo saved! Show a confirmation.
}
override fun onError(exc: ImageCaptureException) {
// Handle the failure.
}
}
)การจัดการผลลัพธ์
เมื่อดำเนินการสำเร็จ OutputFileResults.savedUri จะระบุ URI ของรูปภาพที่บันทึกไว้ คุณสามารถแสดงรูปภาพนั้น (ด้วย Coil) แชร์รูปภาพ หรือแสดง Snackbar เพื่อยืนยันการบันทึกได้
หากเกิดข้อผิดพลาด ImageCaptureException จะบอกว่าเกิดอะไรขึ้น — ให้บันทึกข้อผิดพลาดและแจ้งผู้ใช้
override fun onImageSaved(output: ImageCapture.OutputFileResults) {
val uri = output.savedUri ?: return
Toast.makeText(context, "Saved: $uri", Toast.LENGTH_SHORT).show()
}การเชื่อมต่อปุ่มชัตเตอร์
ใน Compose ให้วางปุ่มชัตเตอร์ทับบนตัวอย่างภาพด้วย Box ย้ายการอ้างอิง ImageCapture ขึ้นไปไว้ในระดับที่เหมาะสม เพื่อให้ onClick ของปุ่มเรียกใช้ takePhoto ได้
Box(modifier = Modifier.fillMaxSize()) {
CameraPreview(imageCapture = imageCapture)
IconButton(
onClick = { takePhoto(context, imageCapture) },
modifier = Modifier
.align(Alignment.BottomCenter)
.padding(32.dp)
) {
Icon(Icons.Default.PhotoCamera, contentDescription = "Take photo")
}
}การแยก takePhoto()
ทำให้ composable ของคุณเป็นระเบียบด้วยการย้ายตรรกะการถ่ายภาพไปไว้ในตัวช่วย ฟังก์ชันนี้รับ context และ use case ImageCapture สร้างตัวเลือกผลลัพธ์ แล้วเรียกใช้ takePicture
fun takePhoto(context: Context, imageCapture: ImageCapture) {
val values = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, "IMG_${System.currentTimeMillis()}")
put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
}
val options = ImageCapture.OutputFileOptions.Builder(
context.contentResolver,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
values
).build()
imageCapture.takePicture(
options,
ContextCompat.getMainExecutor(context),
object : ImageCapture.OnImageSavedCallback {
override fun onImageSaved(o: ImageCapture.OutputFileResults) {}
override fun onError(e: ImageCaptureException) {}
}
)
}แฟลชและการหมุนภาพ
รายละเอียดปิดท้ายสองอย่าง:
- แฟลช: ตั้งค่า
imageCapture.flashModeเป็นFLASH_MODE_ON,OFFหรือAUTO - การหมุนภาพ: CameRX ใช้การหมุนเป้าหมายเพื่อจัดแนว JPEG ที่บันทึกให้ถูกต้อง โปรดอัปเดตค่านี้อยู่เสมอเพื่อให้ทิศทางภาพถูกต้อง
imageCapture.flashMode = ImageCapture.FLASH_MODE_AUTO
// Update target rotation when the device rotates:
imageCapture.targetRotation = display.rotationประกอบทุกอย่างเข้าด้วยกัน
ลำดับการทำงานทั้งหมดของการถ่ายภาพคือ สร้าง ImageCapture → ผูกเข้ากับตัวอย่างภาพ → เมื่อแตะชัตเตอร์ ให้สร้าง OutputFileOptions และเรียกใช้ takePicture → จัดการ onImageSaved / onError
เพียงไม่กี่บรรทัด คุณก็จะมีกล้องที่บันทึกรูปภาพลงแกลเลอรีได้อย่างสมบูรณ์
ตรวจสอบความเข้าใจ
ตรวจสอบว่าคุณเข้าใจลำดับการถ่ายและบันทึกรูปภาพแล้ว
ทบทวน
ขณะนี้คุณสามารถถ่ายและบันทึกรูปภาพด้วย CameRX ได้แล้ว:
- สร้าง use case
ImageCaptureและผูกเข้ากับตัวอย่างภาพ - อธิบายผลลัพธ์ด้วย
ContentValuesและMediaStoreสำหรับพื้นที่จัดเก็บแบบจำกัดขอบเขต - เรียกใช้
takePicture()พร้อมOutputFileOptionsตัวประมวลผล และOnImageSavedCallback - อ่านค่า
savedUriเมื่อดำเนินการสำเร็จ และจัดการImageCaptureExceptionเมื่อเกิดข้อผิดพลาด
ถัดไป คุณจะได้เรียนรู้การบันทึกวิดีโอด้วย use case VideoCapture
คำถามที่พบบ่อย
บทเรียน “การถ่ายภาพ” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การถ่ายภาพ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Android Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Android Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การถ่ายภาพ”
บันทึกและจัดเก็บรูปภาพ คุณปฏิบัติ Android Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Android Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Android Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “การถ่ายภาพ” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Android Academy นี้ได้ไหม
ได้ บทเรียน Android Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ