The sample source was only Kotlin, so I rewrite it in Java. Operation has been verified with the actual machine and API 28 emulator. Please give the camera permission to the application from the Android settings.
Created
September 15, 2019 15:11
-
-
Save moshimore/e8a473cfbbf4ee87a04ea39c88dc69a6 to your computer and use it in GitHub Desktop.
Android CameraX Sample
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<androidx.constraintlayout.widget.ConstraintLayout | |
xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:tools="http://schemas.android.com/tools" | |
xmlns:app="http://schemas.android.com/apk/res-auto" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
tools:context=".MainActivity"> | |
<TextureView | |
android:id="@+id/textureView" | |
android:layout_width="480px" | |
android:layout_height="640px" | |
android:layout_marginTop="16dp" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toTopOf="parent" | |
app:layout_constraintVertical_bias="0" /> | |
<ImageView | |
android:id="@+id/imageView" | |
android:layout_width="480px" | |
android:layout_height="640px" | |
android:layout_margin="16dp" | |
app:srcCompat="@mipmap/ic_launcher" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toBottomOf="@+id/textureView" /> | |
<ImageButton | |
android:id="@+id/imageButton" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_marginBottom="16dp" | |
app:srcCompat="@android:drawable/ic_menu_camera" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintStart_toStartOf="parent" /> | |
</androidx.constraintlayout.widget.ConstraintLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<uses-permission android:name="android.permission.CAMERA" /> | |
<uses-feature android:name="android.hardware.camera" /> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
android { | |
compileSdkVersion 29 | |
defaultConfig { | |
minSdkVersion 21 | |
targetSdkVersion 29 | |
} | |
compileOptions { | |
sourceCompatibility JavaVersion.VERSION_1_8 | |
targetCompatibility JavaVersion.VERSION_1_8 | |
} | |
} | |
dependencies { | |
implementation fileTree(dir: 'libs', include: ['*.jar']) | |
implementation 'androidx.appcompat:appcompat:1.1.0' | |
implementation 'androidx.constraintlayout:constraintlayout:1.1.3' | |
def camerax_version = "1.0.0-alpha05" | |
implementation "androidx.camera:camera-core:${camerax_version}" | |
implementation "androidx.camera:camera-camera2:${camerax_version}" | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import androidx.appcompat.app.AppCompatActivity; | |
import androidx.camera.core.*; | |
import android.graphics.Bitmap; | |
import android.graphics.BitmapFactory; | |
import android.graphics.Matrix; | |
import android.os.Bundle; | |
import android.util.Log; | |
import android.util.Size; | |
import android.view.Surface; | |
import android.view.TextureView; | |
import android.view.View; | |
import android.view.ViewGroup; | |
import android.widget.ImageButton; | |
import android.widget.ImageView; | |
import java.nio.ByteBuffer; | |
public class MainActivity extends AppCompatActivity | |
{ | |
private TextureView textureView; | |
@Override | |
protected void onCreate(Bundle savedInstanceState) | |
{ | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_main); | |
textureView = findViewById(R.id.textureView); | |
textureView.post((Runnable)(new Runnable() | |
{ | |
public final void run() | |
{ | |
startCamera(); | |
} | |
})); | |
textureView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() | |
{ | |
@Override | |
public void onLayoutChange(View view, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) | |
{ | |
updateTransform(); | |
} | |
}); | |
} | |
private void startCamera() | |
{ | |
PreviewConfig.Builder previewConfig = new PreviewConfig.Builder(); | |
Preview preview = new Preview(previewConfig.build()); | |
preview.setOnPreviewOutputUpdateListener(new Preview.OnPreviewOutputUpdateListener() | |
{ | |
@Override | |
public void onUpdated(Preview.PreviewOutput output) | |
{ | |
ViewGroup parent = (ViewGroup) textureView.getParent(); | |
parent.removeView(textureView); | |
parent.addView(textureView, 0); | |
textureView.setSurfaceTexture(output.getSurfaceTexture()); | |
updateTransform(); | |
} | |
}); | |
ImageCaptureConfig.Builder imageCaptureConfig = new ImageCaptureConfig.Builder(); | |
final ImageCapture imageCapture = new ImageCapture(imageCaptureConfig.build()); | |
ImageButton button = findViewById(R.id.imageButton); | |
button.setOnClickListener(new View.OnClickListener() | |
{ | |
@Override | |
public void onClick(View view) | |
{ | |
imageCapture.takePicture(new ImageCapture.OnImageCapturedListener() | |
{ | |
@Override | |
public void onCaptureSuccess(ImageProxy image, int rotationDegrees) | |
{ | |
ImageView imageView = findViewById(R.id.imageView); | |
imageView.setImageBitmap(imageProxyToBitmap(image)); | |
imageView.setRotation(rotationDegrees); | |
image.close(); | |
} | |
}); | |
} | |
}); | |
CameraX.bindToLifecycle(this, preview, imageCapture); | |
} | |
private void updateTransform() | |
{ | |
Matrix matrix = new Matrix(); | |
float centerX = textureView.getWidth() / 2f; | |
float centerY = textureView.getHeight() / 2f; | |
float rotationDegrees = 0f; | |
switch (textureView.getDisplay().getRotation()) | |
{ | |
case Surface.ROTATION_0: | |
rotationDegrees = 0f; | |
break; | |
case Surface.ROTATION_90: | |
rotationDegrees = 90f; | |
break; | |
case Surface.ROTATION_180: | |
rotationDegrees = 180f; | |
break; | |
case Surface.ROTATION_270: | |
rotationDegrees = 270f; | |
break; | |
default: | |
return; | |
} | |
matrix.postRotate(-rotationDegrees, centerX, centerY); | |
textureView.setTransform(matrix); | |
} | |
private Bitmap imageProxyToBitmap(ImageProxy image) | |
{ | |
ImageProxy.PlaneProxy planeProxy = image.getPlanes()[0]; | |
ByteBuffer buffer = planeProxy.getBuffer(); | |
byte[] bytes = new byte[buffer.remaining()]; | |
buffer.get(bytes); | |
return BitmapFactory.decodeByteArray(bytes, 0, bytes.length); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment