Skip to content

Commit

Permalink
Keep screen awake,WIP: freeze stream
Browse files Browse the repository at this point in the history
  • Loading branch information
0xf104a committed Oct 25, 2023
1 parent 455db1f commit f239591
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 9 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ android {
minSdk 26
targetSdk 33
versionCode 1
versionName "1.0"
versionName "1.0.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
Expand Down
124 changes: 124 additions & 0 deletions app/src/main/java/com/polar/mirror/FreezeController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package com.polar.mirror;

import static androidx.core.content.ContextCompat.getMainExecutor;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Camera;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.media.Image;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;

import androidx.annotation.NonNull;
import androidx.annotation.OptIn;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ExperimentalGetImage;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageCaptureException;
import androidx.camera.core.ImageProxy;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.view.PreviewView;
import androidx.lifecycle.LifecycleOwner;

import com.google.android.material.floatingactionbutton.FloatingActionButton;

import java.io.File;
import java.nio.ByteBuffer;

/**
* Controls freezing camera view
*/
public class FreezeController {
private static final String TAG = "FreezeController";
private final FloatingActionButton mFreezeButton;
private final PreviewView mCameraView;
private final ImageView mFreezeView;
private final ImageCapture mImageCapture;
private final Context mContext;
private boolean mCameraFrozen = false;

FreezeController(Context context, FloatingActionButton freezeButton, PreviewView cameraView,
ImageView freezeView){
mFreezeButton = freezeButton;
mCameraView = cameraView;
mFreezeView = freezeView;
mContext = context;
mImageCapture = new ImageCapture.Builder()
.setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
.build();
}

/**
* Should be called when camera is ready
* @param provider camera provider
* @param lcOwner lifecycle owner used for binding camera usecases
*/
public void onCameraInitialized(ProcessCameraProvider provider, LifecycleOwner lcOwner){
CameraSelector cameraSelector = new CameraSelector.Builder()
.requireLensFacing(CameraSelector.LENS_FACING_FRONT)
.build();
provider.bindToLifecycle(lcOwner, cameraSelector, mImageCapture);
Log.d(TAG, "completed onCameraInitialized");
}


private void setFrozenImage(){
mImageCapture.takePicture(getMainExecutor(mContext),
new ImageCapture.OnImageCapturedCallback() {

@Override
@SuppressLint("UnsafeOptInUsageError")
public void onCaptureSuccess(@NonNull ImageProxy imageProxy){
Log.i(TAG, "Capture success");
Image image = imageProxy.getImage();
if(image == null){
Log.e(TAG, "Image is null");
return;
}
int format = image.getFormat();
if(format != ImageFormat.JPEG){
Log.e(TAG, "Expected JPEG format, got format " + format);
return;
}
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
Matrix matrix = new Matrix();
matrix.postRotate(270);
bitmap = Bitmap.createBitmap(
bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true
);
mFreezeView.setImageBitmap(bitmap);
imageProxy.close();
}

@Override
public void onError(@NonNull ImageCaptureException exception) {
Log.e(TAG, "Can not capture image");
exception.printStackTrace();
}
});
}

/**
* Toggles camera freeze
*/
public void toggleFreeze(){
if(mCameraFrozen){
mFreezeView.setVisibility(View.GONE);
mCameraView.setVisibility(View.VISIBLE);
mCameraFrozen = false;
} else {
setFrozenImage();
mCameraView.setVisibility(View.GONE);
mFreezeView.setVisibility(View.VISIBLE);
mCameraFrozen = true;
}
}
}
20 changes: 12 additions & 8 deletions app/src/main/java/com/polar/mirror/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;

import com.google.android.material.floatingactionbutton.FloatingActionButton;

import java.util.concurrent.ExecutionException;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private PreviewView mCameraView;
private boolean mCameraFrozen = false;
private FreezeController mFreezeController;
private final static String TAG = "MainActivity";

@Override
Expand All @@ -30,6 +31,14 @@ protected void onCreate(Bundle savedInstanceState) {
setupView();

mCameraView = findViewById(R.id.preview_view);

//Initialize freeze controller
FloatingActionButton freezeButton = findViewById(R.id.freeze_button);
ImageView freezeView = findViewById(R.id.stop_view);
mFreezeController = new FreezeController(this, freezeButton, mCameraView,
freezeView);

//Start camera
try {
startCamera();
} catch (ExecutionException | InterruptedException e) {
Expand Down Expand Up @@ -94,6 +103,7 @@ private void startCamera() throws ExecutionException, InterruptedException {
.build();
cameraProvider.unbindAll();
cameraProvider.bindToLifecycle((LifecycleOwner)this, cameraSelector, preview);
mFreezeController.onCameraInitialized(cameraProvider, (LifecycleOwner)this);
} catch (Exception e) {
e.printStackTrace();
}
Expand All @@ -103,13 +113,7 @@ private void startCamera() throws ExecutionException, InterruptedException {
* Toggles camera freeze mode
*/
private void toggleCameraFreeze(){
if(!mCameraFrozen) {
mCameraView.setVisibility(View.GONE);
mCameraFrozen = true;
} else {
mCameraView.setVisibility(View.VISIBLE);
mCameraFrozen = false;
}
mFreezeController.toggleFreeze();
}

@Override
Expand Down
8 changes: 8 additions & 0 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,21 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true"
tools:context=".MainActivity">

<androidx.camera.view.PreviewView
android:id="@+id/preview_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />

<ImageView
android:id="@+id/stop_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:contentDescription="@string/stop_view_desc" />

<include layout="@layout/action_panel" />

</androidx.constraintlayout.widget.ConstraintLayout>
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
<string name="app_name">Mirror</string>
<string name="exit">Exit app</string>
<string name="freeze">Freeze</string>
<string name="stop_view_desc">Image displaying stop-frame</string>
</resources>

0 comments on commit f239591

Please sign in to comment.