แอป Android ทำงานบนฟอร์มแฟกเตอร์ที่หลากหลายกว่าแค่โทรศัพท์ที่ถือในโหมดแนวตั้ง เมื่อมีการเปิดตัวหน้าต่างเดสก์ท็อป จอแสดงผลที่เชื่อมต่อ และอุปกรณ์แบบพับได้ แอปกล้องของคุณต้องปรับให้เข้ากับขนาดหน้าต่างแบบไดนามิก สัดส่วนภาพที่แตกต่างกัน และฮาร์ดแวร์ภายนอก
เหตุผลที่ตรรกะของโทรศัพท์ใช้งานไม่ได้
แอปกล้องมักจะตั้งสมมติฐานที่ทำให้เกิดข้อผิดพลาดร้ายแรงในสภาพแวดล้อมที่มีฟอร์มแฟกเตอร์หลายแบบ
การวางแนวตามธรรมชาติ
- สมมติฐาน: การวางแนวตามธรรมชาติของอุปกรณ์
ROTATION_0จะเป็นแนวตั้งเสมอ - ความเป็นจริง: ในแท็บเล็ต หน้าจอด้านในของอุปกรณ์แบบพับได้บางรุ่น และจอภาพเดสก์ท็อป
ROTATION_0มักจะเป็นแนวนอน - ผลลัพธ์: ตัวอย่างหมุน 90 องศาอย่างไม่ถูกต้อง
การจัดแนวเซ็นเซอร์
- สมมติฐาน: ขอบยาวของเซ็นเซอร์กล้องจะจัดแนวกับขอบยาวของหน้าจอ
- ความเป็นจริง: หน้าต่างที่ปรับขนาดได้อาจเป็นสี่เหลี่ยมจัตุรัสหรือแนวนอน ในขณะที่เซ็นเซอร์ยังคงอยู่กับที่ (โดยปกติคือ 4:3)
- ผลลัพธ์: รูปภาพยืดหรือบิดเบี้ยว
ความหนาแน่นและขนาดของหน้าจอ
- สมมติฐาน: ความหนาแน่นและขนาดของหน้าจอไม่เปลี่ยนแปลงในขณะรันไทม์
- ความเป็นจริง: ในสภาพแวดล้อมเดสก์ท็อป ผู้ใช้จะปรับขนาดหน้าต่างได้อย่างอิสระ
- ผลลัพธ์: การรีสตาร์ทเซสชันกล้องในทุกเหตุการณ์การลากจะขัดขวางประสบการณ์ของผู้ใช้และอาจทำให้เกิดข้อขัดข้อง
โซลูชันที่ 1: ใช้ Intent ของระบบ
หากแอปของคุณต้องถ่ายรูปหรือวิดีโอ แต่ไม่จำเป็นต้องมีอินเทอร์เฟซกล้องที่กำหนดเองแบบพิเศษ วิธีที่ดีที่สุดในการจัดการฟอร์มแฟกเตอร์ต่างๆ คือการเปิดกล้องของระบบที่ติดตั้งไว้ล่วงหน้าของอุปกรณ์ (ดู Intent ของกล้อง)
การใช้ Intent ของระบบจะมอบประสบการณ์การถ่ายภาพทั้งหมดให้กับแอปกล้องที่พัฒนาโดยผู้ผลิตอุปกรณ์ดั้งเดิม (OEM) ของอุปกรณ์ ซึ่งเป็นการ เอาต์ซอร์ส ความซับซ้อนของการรองรับฟอร์มแฟกเตอร์อย่างมีประสิทธิภาพ ซึ่งรวมถึงสิ่งต่อไปนี้
- การรองรับการปรับขนาดและการหมุนในตัว \- ผู้ผลิตสร้างแอปกล้องเริ่มต้นในอุปกรณ์แบบพับได้หรือแท็บเล็ตขึ้นมาโดยเฉพาะเพื่อจัดการกับรูปทรงเรขาคณิตของอุปกรณ์นั้นๆ แอปได้รับการออกแบบมาให้ทำงานอย่างถูกต้องเมื่ออุปกรณ์กางออก หมุน หรือเข้าสู่โหมดหลายหน้าต่าง
- การเข้าถึงฟีเจอร์ฮาร์ดแวร์ขั้นสูง \- แอปกล้อง OEM มีสิทธิ์เข้าถึงอัลกอริทึมที่ปรับแต่งฮาร์ดแวร์ (โหมดกลางคืน, HDR, การสลับเลนส์เฉพาะ) ซึ่งยากหรือเป็นไปไม่ได้ที่จะจำลองด้วยตนเอง
โซลูชันที่ 2: ใช้ Jetpack CameraX
CameraX เป็นไลบรารี Jetpack ที่สร้างขึ้นเพื่อช่วยให้การพัฒนาแอปกล้อง ง่ายขึ้น CameraX ตระหนักถึงวงจรการทำงานและมุ่งเน้นที่ Surface CameraX จะจัดการการกำหนดค่าใหม่ของเซสชันกล้องโดยอัตโนมัติระหว่างการปรับขนาดหลายหน้าต่างหรือเมื่อแอปย้ายไปยังจอแสดงผลที่เชื่อมต่อ ซึ่งช่วยให้สตรีมตัวอย่างปรับเปลี่ยนได้โดยไม่กระตุกหรือยืดออก ซึ่งแตกต่างจาก Camera2 ที่ต้องคำนวณการวางแนวเซ็นเซอร์และขนาด Surface ใหม่ด้วยตนเองทุกครั้งที่อุปกรณ์พับ หมุน หรือปรับขนาด
คอมโพเนนต์ต่างๆ เช่น PreviewView จะจัดการสัดส่วนภาพและ
ประเภทการปรับขนาดอย่างชาญฉลาดในสถานะต่างๆ เช่น อุปกรณ์แบบพับได้เปลี่ยนจากหน้าจอด้านนอกเป็นหน้าจอด้านใน ซึ่งช่วยให้คุณรองรับฮาร์ดแวร์ที่หลากหลายด้วย
การใช้งานที่สอดคล้องกันเพียงครั้งเดียว แทนที่จะต้องจัดการกับกรณีพิเศษที่ซับซ้อนของ
อุปกรณ์แต่ละรุ่น
เขียน
ใช้ไลบรารี androidx.camera:camera-compose
โดยเฉพาะกับ Jetpack Compose ไลบรารีมีคอมโพสได้ CameraXViewfinder ซึ่ง
ออกแบบมาโดยเฉพาะเพื่อจัดการกับรูปทรงเรขาคณิตที่ซับซ้อนของการปรับขนาด การหมุน และ
สัดส่วนภาพภายในวงจรการทำงานของ Compose
คอมโพเนนต์ CameraXViewfinder ช่วยลดแหล่งที่มาของข้อผิดพลาดที่พบบ่อยที่สุดในแอปกล้อง
- การแปลงพิกัดอัตโนมัติ \- ส่วนที่ยากที่สุดอย่างหนึ่งในการสร้างแอปกล้องคือการจับคู่การแตะของผู้ใช้ (พิกัด x, y บนหน้าจอ) กับระบบพิกัดของเซ็นเซอร์กล้อง (0-1, 0-1 หมุน) สำหรับการโฟกัสและการวัดแสง
CameraXViewfinderมีCoordinateTransformerที่ จัดการการคำนวณทางคณิตศาสตร์โดยอัตโนมัติ แม้ว่าจะมีการปรับขนาดหน้าต่างหรือ พับอุปกรณ์ก็ตาม - ลักษณะการทำงานของเลย์เอาต์ที่ถูกต้อง \-
CameraXViewfinderทำงานอย่างถูกต้องกับการจัดลำดับตามแกน Z ของ Compose ซึ่งแตกต่างจากSurfaceViewหรือTextureViewคุณสามารถวางซ้อนองค์ประกอบ UI (วงแหวนโฟกัส, การควบคุม) หรือใช้ตัวปรับแต่ง (มุมโค้งมน, ภาพเคลื่อนไหว) ได้โดยไม่มีสิ่งประดิษฐ์การแสดงผล - การปรับขนาดและสัดส่วนภาพ:
CameraXViewfinderจะจัดการตรรกะ ครอบตัดตรงกลาง เทียบกับ พอดีตรงกลาง ภายใน ซึ่งช่วยให้ตัวอย่างไม่ ยืดออกเมื่อมีการปรับขนาดหน้าต่างแอปเป็นสัดส่วนภาพที่ไม่เป็นมาตรฐาน (เช่น โหมดแยกหน้าจอหรือโหมดหน้าต่างเดสก์ท็อป)
มุมมอง
ในแอปที่อิงตาม View ให้ใช้ PreviewView หรือ ViewFinderView หากคุณใช้
SurfaceView หรือ TextureView โดยตรง คุณต้องคำนวณสัดส่วนภาพและ
ใช้ เมทริกซ์การแปลง ที่ถูกต้องด้วยตนเอง
โซลูชันที่ 3: จัดการการวางแนวและการปรับขนาดแบบไดนามิก
เมื่อใช้ API ของแพลตฟอร์ม โดยตรง ให้คำนึงถึงการหมุนอุปกรณ์ การรีสตาร์ทกิจกรรม และสัดส่วนภาพ
หยุดใช้การหมุนอุปกรณ์
อย่าใช้ Display#getRotation() หรือการวางแนวเซ็นเซอร์ทางกายภาพเพียงอย่างเดียว
เพื่อกำหนดเลย์เอาต์ของ UI
- ใช้เมตริกหน้าต่าง \- กำหนดเลย์เอาต์ (UI แนวนอนเทียบกับแนวตั้ง
) โดยเปรียบเทียบความกว้างและความสูงของ หน้าต่างแอป โดยใช้
WindowManager#getCurrentWindowMetrics() - ละเว้นการวางแนวตามธรรมชาติ \- แอปของคุณอาจอยู่ในหน้าต่างรูปทรงแนวตั้งบนจอภาพแนวนอน การวางแนวอุปกรณ์ไม่เกี่ยวข้องกับขอบเขต UI
หลีกเลี่ยงการรีสตาร์ทกิจกรรม
ลักษณะการทำงานเริ่มต้นของ Android จะทำลายกิจกรรมของแอปเมื่อมีการเปลี่ยนแปลงการกำหนดค่า (เช่น การปรับขนาดหน้าต่าง) สำหรับแอปกล้อง ลักษณะนี้จะปรากฏเป็นการกะพริบของจอแสดงผลหรือการเชื่อมต่อขาดหายระหว่างวิดีโอคอล
- การกำหนดค่าไฟล์ Manifest \- ประกาศการเปลี่ยนแปลงการกำหนดค่าใน ไฟล์ Manifest เพื่อจัดการการปรับขนาดโดยไม่ต้องรีสตาร์ท
- การอัปเดตแบบไดนามิก \- ใน
onConfigurationChanged()ให้อัปเดตพารามิเตอร์เลย์เอาต์ของตัวอย่างกล้อง ให้ตรงกับขนาดหน้าต่างใหม่
สัดส่วนภาพและการครอบตัด
ปัญหาที่พบบ่อยในอุปกรณ์แบบพับได้และหน้าต่างเดสก์ท็อปคือ การยืดตัวอย่าง ซึ่งฟีดกล้อง 4:3 ถูกบังคับให้แสดงในหน้าต่าง 16:9 หรือ 1:1
- ไม่ยืด \- อย่าบังคับให้บัฟเฟอร์กล้องตรงกับขอบเขต View อย่างแน่นอนหากสัดส่วนภาพของตัวอย่างและหน้าต่างแตกต่างกัน
- ครอบตัดตรงกลาง (แนะนำ): ปรับขนาดตัวอย่างให้เต็มมิติที่สั้นที่สุดของหน้าต่างและครอบตัดส่วนเกิน วิธีนี้จะช่วยให้วัตถุไม่บิดเบี้ยวและเต็มเฟรม
- พอดีตรงกลาง (ทางเลือก): หากการแสดงขอบเขตการมองเห็นทั้งหมดมีความสำคัญ (เช่น การสแกนเอกสาร) ให้ใส่แถบดำด้านบนและด้านล่างตัวอย่างภายในหน้าต่าง
โบนัส: การรองรับประสบการณ์การใช้งานที่เหมาะกับอุปกรณ์แบบพับได้
อุปกรณ์แบบพับได้ไม่ได้เป็นแค่โทรศัพท์ที่งอได้ แต่ยังมีสถานะฮาร์ดแวร์ที่ไม่เหมือนใครซึ่งสามารถปรับปรุงวิธีที่ผู้ใช้ถ่ายรูปและวิดีโอได้อย่างมาก แทนที่จะมองว่าการพับเป็นปัญหาที่ต้องแก้ไข ให้ใช้การพับเพื่อสร้างฟีเจอร์ที่อุปกรณ์ที่ไม่ใช่แบบพับได้ทำไม่ได้
โหมดตั้งโต๊ะ (การถ่ายภาพแบบแฮนด์ฟรี)
โหมดตั้งโต๊ะช่วยให้ผู้ใช้พับอุปกรณ์ครึ่งหนึ่งและวางบนพื้นผิว เพื่อวิดีโอคอลเป็นเวลานาน การถ่ายภาพไทม์แลปส์ และการถ่ายภาพกลางคืนแบบเปิดรับแสงนาน
โหมดจอแสดงผลด้านหลัง (เซลฟีคุณภาพสูง)
- ในอุปกรณ์แบบพับได้ กล้องหลังมักจะมีคุณภาพสูงกว่ากล้องที่หันเข้าหาผู้ใช้ โหมดจอแสดงผลด้านหลังช่วยให้ผู้ใช้กางอุปกรณ์ออกและหมุน อุปกรณ์ โดยใช้หน้าจอด้านนอกขนาดเล็กเป็นช่องมองภาพสดสำหรับกล้องหลัง หลัก
- โหมดจอแสดงผลด้านหลังช่วยให้ถ่ายเซลฟีความละเอียด 50MP ขึ้นไป ถ่ายภาพหมู่แบบอัลตร้าไวด์ และถ่ายวิดีโอคุณภาพสูงได้โดยไม่ต้องพกอุปกรณ์เพิ่มเติม
โหมด 2 หน้าจอ (การแสดงตัวอย่างวัตถุ)
- โหมด 2 หน้าจอ ช่วยให้คุณแสดงตัวอย่างกล้องบนหน้าจอด้านใน และด้านนอก ทั้งคู่ พร้อมกันได้ โหมดนี้เหมาะอย่างยิ่งสำหรับการถ่ายภาพบุคคล โดยวัตถุที่ถ่ายจะเห็นตัวเองบนหน้าจอด้านนอกและปรับท่าทางได้ในขณะที่คุณจัดเฟรมภาพบนหน้าจอด้านใน
- โหมด 2 หน้าจอจะสร้างหน้าต่างการนำเสนอรองบนหน้าจอด้านนอก ซึ่งแตกต่างจากโหมดจอแสดงผลด้านหลัง (ซึ่งย้าย ทั้ง แอป)