You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何将Camera2 API设为标准相机?Camera2 API竖屏图片显示问题

Hey there, let's break down your two Camera2-related questions and solve them step by step!

问题1:如何将Camera2 API设置为标准相机?

First off, let's clarify: when we talk about the "standard camera" on Android, we're referring to the system's default camera app. If you want to build your own camera app using Camera2 API and set it as the system's default camera, here's what you need to do:

  • Declare required permissions: You'll need the CAMERA permission (mandatory for camera access). For Android 10+, if you're saving photos to public storage, add WRITE_EXTERNAL_STORAGE (or use MediaStore for scoped storage instead). Don't forget to request runtime permissions for these as well!

  • Add Intent Filters to your camera Activity: This lets the system recognize your app as a valid camera option. Add these filters in your AndroidManifest.xml:

<activity android:name=".YourCameraActivity">
    <!-- For image capture -->
    <intent-filter>
        <action android:name="android.media.action.IMAGE_CAPTURE" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
    <!-- For video capture (optional) -->
    <intent-filter>
        <action android:name="android.media.action.VIDEO_CAPTURE" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>
  • Handle incoming camera requests: Make sure your Activity can process the intent data passed from other apps (like the output Uri for saving photos). Once your app meets these requirements, users can go to system settings and select your app as the default camera.
问题2:Camera2Basic示例拍摄的图片无法竖屏显示

This is a super common issue with Camera2 API, and it boils down to image orientation metadata (Exif) not being handled properly or incorrect output configuration during capture. Let's cover two reliable fixes:

Fix 1: Rotate the Bitmap using Exif data when displaying

When you decode the image with BitmapFactory, it doesn't automatically apply the orientation stored in the image's Exif data. Here's how to fix that:

fun getRotatedBitmap(filePath: String): Bitmap? {
    // Get Exif orientation info
    val exif = ExifInterface(filePath)
    val orientation = exif.getAttributeInt(
        ExifInterface.TAG_ORIENTATION,
        ExifInterface.ORIENTATION_NORMAL
    )

    // Decode the original bitmap
    val originalBitmap = BitmapFactory.decodeFile(filePath) ?: return null

    // Rotate the bitmap based on Exif orientation
    return when (orientation) {
        ExifInterface.ORIENTATION_ROTATE_90 -> rotateBitmap(originalBitmap, 90f)
        ExifInterface.ORIENTATION_ROTATE_180 -> rotateBitmap(originalBitmap, 180f)
        ExifInterface.ORIENTATION_ROTATE_270 -> rotateBitmap(originalBitmap, 270f)
        else -> originalBitmap
    }
}

private fun rotateBitmap(bitmap: Bitmap, degrees: Float): Bitmap {
    val matrix = Matrix()
    matrix.postRotate(degrees)
    return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
}

Then use this getRotatedBitmap method instead of directly decoding the file, and set the returned bitmap to your ImageView.

Fix 2: Configure Camera2 to capture in portrait orientation directly

You can adjust the Camera2 capture setup to output portrait images natively. Modify the Camera2Basic sample code like this:

  1. Adjust ImageReader dimensions for portrait:
// Get device display rotation
val rotation = windowManager.defaultDisplay.rotation
val displaySize = Point()
windowManager.defaultDisplay.getSize(displaySize)

// Swap width/height based on rotation to match portrait
val outputWidth = if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) {
    displaySize.height
} else {
    displaySize.width
}
val outputHeight = if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) {
    displaySize.width
} else {
    displaySize.height
}

// Create ImageReader with adjusted dimensions
mImageReader = ImageReader.newInstance(outputWidth, outputHeight, ImageFormat.JPEG, 2)
  1. Set JPEG orientation in CaptureRequest:
val captureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE)
captureBuilder.addTarget(mImageReader.surface)

// Calculate and set correct JPEG orientation
val characteristics = cameraManager.getCameraCharacteristics(mCameraId)
captureBuilder.set(
    CaptureRequest.JPEG_ORIENTATION,
    getJpegOrientation(rotation, characteristics)
)
  1. Add the orientation calculation helper method:
private fun getJpegOrientation(displayRotation: Int, characteristics: CameraCharacteristics): Int {
    val sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION)!!
    return when (displayRotation) {
        Surface.ROTATION_0 -> sensorOrientation
        Surface.ROTATION_90 -> (sensorOrientation + 270) % 360
        Surface.ROTATION_180 -> (sensorOrientation + 180) % 360
        Surface.ROTATION_270 -> (sensorOrientation + 90) % 360
        else -> sensorOrientation
    }
}

This way, the captured image will already be in the correct portrait orientation, no extra rotation needed when displaying.

内容的提问来源于stack exchange,提问作者D T

火山引擎 最新活动