รองรับกล้องในอุปกรณ์หลายรูปแบบ

แอป Android ทำงานบนฟอร์มแฟกเตอร์ที่หลากหลายกว่าแค่โทรศัพท์ที่ถือในโหมดแนวตั้ง เมื่อมีการเปิดตัวหน้าต่างเดสก์ท็อป จอแสดงผลที่เชื่อมต่อ และอุปกรณ์แบบพับได้ แอปกล้องของคุณต้องปรับให้เข้ากับขนาดหน้าต่างแบบไดนามิก สัดส่วนภาพที่แตกต่างกัน และฮาร์ดแวร์ภายนอก

รูปที่ 1 ตัวอย่างแอปกล้องบนจอแสดงผลต่างๆ

เหตุผลที่ตรรกะของโทรศัพท์ใช้งานไม่ได้

แอปกล้องมักจะตั้งสมมติฐานที่ทำให้เกิดข้อผิดพลาดร้ายแรงในสภาพแวดล้อมที่มีฟอร์มแฟกเตอร์หลายแบบ

การวางแนวตามธรรมชาติ

  • สมมติฐาน: การวางแนวตามธรรมชาติของอุปกรณ์ ROTATION_0 จะเป็นแนวตั้งเสมอ
  • ความเป็นจริง: ในแท็บเล็ต หน้าจอด้านในของอุปกรณ์แบบพับได้บางรุ่น และจอภาพเดสก์ท็อป ROTATION_0 มักจะเป็นแนวนอน
  • ผลลัพธ์: ตัวอย่างหมุน 90 องศาอย่างไม่ถูกต้อง
รูปที่ 2 ช่องมองภาพของกล้องก่อนและหลังใช้การหมุนที่ถูกต้อง

การจัดแนวเซ็นเซอร์

  • สมมติฐาน: ขอบยาวของเซ็นเซอร์กล้องจะจัดแนวกับขอบยาวของหน้าจอ
  • ความเป็นจริง: หน้าต่างที่ปรับขนาดได้อาจเป็นสี่เหลี่ยมจัตุรัสหรือแนวนอน ในขณะที่เซ็นเซอร์ยังคงอยู่กับที่ (โดยปกติคือ 4:3)
  • ผลลัพธ์: รูปภาพยืดหรือบิดเบี้ยว
รูปที่ 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 จะทำลายกิจกรรมของแอปเมื่อมีการเปลี่ยนแปลงการกำหนดค่า (เช่น การปรับขนาดหน้าต่าง) สำหรับแอปกล้อง ลักษณะนี้จะปรากฏเป็นการกะพริบของจอแสดงผลหรือการเชื่อมต่อขาดหายระหว่างวิดีโอคอล

สัดส่วนภาพและการครอบตัด

ปัญหาที่พบบ่อยในอุปกรณ์แบบพับได้และหน้าต่างเดสก์ท็อปคือ การยืดตัวอย่าง ซึ่งฟีดกล้อง 4:3 ถูกบังคับให้แสดงในหน้าต่าง 16:9 หรือ 1:1

  • ไม่ยืด \- อย่าบังคับให้บัฟเฟอร์กล้องตรงกับขอบเขต View อย่างแน่นอนหากสัดส่วนภาพของตัวอย่างและหน้าต่างแตกต่างกัน
  • ครอบตัดตรงกลาง (แนะนำ): ปรับขนาดตัวอย่างให้เต็มมิติที่สั้นที่สุดของหน้าต่างและครอบตัดส่วนเกิน วิธีนี้จะช่วยให้วัตถุไม่บิดเบี้ยวและเต็มเฟรม
  • พอดีตรงกลาง (ทางเลือก): หากการแสดงขอบเขตการมองเห็นทั้งหมดมีความสำคัญ (เช่น การสแกนเอกสาร) ให้ใส่แถบดำด้านบนและด้านล่างตัวอย่างภายในหน้าต่าง

โบนัส: การรองรับประสบการณ์การใช้งานที่เหมาะกับอุปกรณ์แบบพับได้

อุปกรณ์แบบพับได้ไม่ได้เป็นแค่โทรศัพท์ที่งอได้ แต่ยังมีสถานะฮาร์ดแวร์ที่ไม่เหมือนใครซึ่งสามารถปรับปรุงวิธีที่ผู้ใช้ถ่ายรูปและวิดีโอได้อย่างมาก แทนที่จะมองว่าการพับเป็นปัญหาที่ต้องแก้ไข ให้ใช้การพับเพื่อสร้างฟีเจอร์ที่อุปกรณ์ที่ไม่ใช่แบบพับได้ทำไม่ได้

โหมดตั้งโต๊ะ (การถ่ายภาพแบบแฮนด์ฟรี)

โหมดตั้งโต๊ะช่วยให้ผู้ใช้พับอุปกรณ์ครึ่งหนึ่งและวางบนพื้นผิว เพื่อวิดีโอคอลเป็นเวลานาน การถ่ายภาพไทม์แลปส์ และการถ่ายภาพกลางคืนแบบเปิดรับแสงนาน

รูปที่ 5 แอปการสื่อสารในโหมดตั้งโต๊ะ: ช่องมองภาพของกล้องอยู่ด้านบนของบานพับ และการควบคุมอยู่ด้านล่าง

โหมดจอแสดงผลด้านหลัง (เซลฟีคุณภาพสูง)

  • ในอุปกรณ์แบบพับได้ กล้องหลังมักจะมีคุณภาพสูงกว่ากล้องที่หันเข้าหาผู้ใช้ โหมดจอแสดงผลด้านหลังช่วยให้ผู้ใช้กางอุปกรณ์ออกและหมุน อุปกรณ์ โดยใช้หน้าจอด้านนอกขนาดเล็กเป็นช่องมองภาพสดสำหรับกล้องหลัง หลัก
  • โหมดจอแสดงผลด้านหลังช่วยให้ถ่ายเซลฟีความละเอียด 50MP ขึ้นไป ถ่ายภาพหมู่แบบอัลตร้าไวด์ และถ่ายวิดีโอคุณภาพสูงได้โดยไม่ต้องพกอุปกรณ์เพิ่มเติม

โหมด 2 หน้าจอ (การแสดงตัวอย่างวัตถุ)

  • โหมด 2 หน้าจอ ช่วยให้คุณแสดงตัวอย่างกล้องบนหน้าจอด้านใน และด้านนอก ทั้งคู่ พร้อมกันได้ โหมดนี้เหมาะอย่างยิ่งสำหรับการถ่ายภาพบุคคล โดยวัตถุที่ถ่ายจะเห็นตัวเองบนหน้าจอด้านนอกและปรับท่าทางได้ในขณะที่คุณจัดเฟรมภาพบนหน้าจอด้านใน
  • โหมด 2 หน้าจอจะสร้างหน้าต่างการนำเสนอรองบนหน้าจอด้านนอก ซึ่งแตกต่างจากโหมดจอแสดงผลด้านหลัง (ซึ่งย้าย ทั้ง แอป)
รูปที่ 5 แอปกล้องในโหมด 2 หน้าจอ