I'm trying to simply change the background color of a TextureView. I would expect this colour to be seen through the semi-transparent camera preview. For some reason it doesn't. If I remove the camera preview altogether from onSurfaceTextureAvailable the view remains white (or can't be seen). Any ideas? I'm trying to achieve a TextureView box that sometimes contains camera preview and other times is a plain colour of my choosing. Thanks.
import android.graphics.Color;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.Surface;
import android.view.TextureView;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import java.io.IOException;
public class MainActivity extends Activity {
private TextureView mTextureView;
FrameLayout screenFrame;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
screenFrame = (FrameLayout)findViewById(R.id.screenFrame);
setVideoScreens();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private void setVideoScreens()
{
final LiveCameraActivity livecam = new LiveCameraActivity();
mTextureView = new TextureView(this);
mTextureView.setSurfaceTextureListener(livecam);
FrameLayout mainFrame = (FrameLayout)findViewById(R.id.mainFrame);
mainFrame.addView(mTextureView);
int width = 640;
int height = 480;
mTextureView.setLayoutParams(new FrameLayout.LayoutParams(
width, height));
mTextureView.setY(200);
mTextureView.setX(200);
mTextureView.setBackgroundColor(Color.BLUE);
mTextureView.setAlpha(.5f);
}
public class LiveCameraActivity extends Activity implements TextureView.SurfaceTextureListener
{
private Camera mCamera;
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height)
{
mCamera = Camera.open();
try
{
mCamera.setPreviewTexture(surface);
mCamera.startPreview();
}
catch (IOException ioe)
{
// Something bad happened
}
}
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height)
{
// Ignored, Camera does all the work for us
}
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface)
{
mCamera.stopPreview();
mCamera.release();
return true;
}
public void onSurfaceTextureUpdated(SurfaceTexture surface)
{
// Invoked every time there's a new Camera preview frame
}
}
}
My solution was to set opaque to false:
textureView.setOpaque(false);
but, when you do that the background color of the TextureView will be irrelevant. So - I've put my TextureView inside a FrameLayout and set its background color. When you do that the FrameLayout background color is the color you see 'behind', or if the TextureView is empty.
Related
I am new to opencv. I want to apply sobel filter on real time video using opencv in android but i am failed in doing so. when i use the built-in function of sobel in opencv it gives me the white blank screen.I have searched a lot but didn't find my error..
package com.example.bismanawaz.opencvpractice;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SurfaceView;
import android.view.WindowManager;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Mat;
import org.opencv.imgproc.Imgproc;
public class MainActivity extends Activity implements CameraBridgeViewBase.CvCameraViewListener2{
private CameraBridgeViewBase mOpenCvCameraView;
private Mat sobell;
public static final int CV_8UC1=0;
private static final String TAG ="OpenCV" ;
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
#Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
Log.i(TAG, "OpenCV loaded successfully");
mOpenCvCameraView.enableView();
} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
};
#Override
public void onResume()
{
super.onResume();
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_7, this, mLoaderCallback);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i(TAG, "called onCreate");
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_main);
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.HelloOpenCvView);
mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
mOpenCvCameraView.setCvCameraViewListener(this);
}
#Override
public void onPause()
{
super.onPause();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
public void onDestroy() {
super.onDestroy();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* This method is invoked when camera preview has started. After this method is invoked
* the frames will start to be delivered to client via the onCameraFrame() callback.
*
* #param width - the width of the frames that will be delivered
* #param height - the height of the frames that will be delivered
*/
#Override
public void onCameraViewStarted(int width, int height) {
sobell = new Mat();
}
/**
* This method is invoked when camera preview has been stopped for some reason.
* No frames will be delivered via onCameraFrame() callback after this method is called.
*/
#Override
public void onCameraViewStopped() {
}
/**
* This method is invoked when delivery of the frame needs to be done.
* The returned values - is a modified frame which needs to be displayed on the screen.
*
* #param inputFrame
*/
#Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
Imgproc.Sobel(inputFrame.gray(),sobell,CV_8UC1,1,1,3);
return sobell;
}
}
This is my method which is doing Sobel.
public static Mat FindSobelEdges(Mat mat) {
Imgproc.Sobel(mat, mat, CvType.CV_8UC1, 1, 1);
return mat;
}
I think your problem is wrong parameters. Pls check the Imgproc.Sobel doc:
Imgproc.Sobel
I have the following java code:
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import com.testing.CameraOperations;
public class MainActivity extends Activity {
private SurfaceView surface;
private CameraOperations camera;
private SoundOperations sound;
private static boolean woken = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#SuppressWarnings("unused")
public void test(View v){
if(!woken){
surface = (SurfaceView)findViewById(R.id.cameraView);
SurfaceHolder holder = surface.getHolder();
surface.setCamera(camera.toggleFaceCamera());
Animation out = AnimationUtils.makeOutAnimation(this, true);
v.startAnimation(out);
v.setVisibility(View.INVISIBLE);
woken = true;
}
}
}
And another class cameraOperations:
import android.hardware.Camera;
public class CameraOperations{
private Camera cam = null;
private Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
private static int camNumber = Camera.getNumberOfCameras();
public Camera toggleFaceCamera(){
if(cam == null){
for(int counter = 0; counter < camNumber; counter++){
Camera.getCameraInfo(counter, cameraInfo);
if(cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT){
try{
cam = Camera.open(counter);
return cam;
}catch(RuntimeException e){return null;}
}
}
}
return null;
}
}
The function "test" is ran by button onclick and the animation works just fine. I've read a bunch of tutorials and references to this BUT I haven't been able to successfully preview the camera to the user. If someone could actually make me understand clearly and by coding the relation between the surface, the holder and the camera preview I would be much thankful!
My objective is as simple as to have my own flashlight app; I have researched both the android developer site and stackoverflow quite thoroughly but seem to lack the connecting bits:
package my.torch;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.CompoundButton;
public class MainActivity extends Activity {
/* public static Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e){
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
*/
Camera mCamera;
CompoundButton mTorch;
Parameters camParams;
private Context context;
AlertDialog.Builder builder;
AlertDialog alertDialog;
public SurfaceView surfaceView;
public SurfaceHolder surfaceHolder;
public String flashMode = null;
/** A safe way to get an instance of the Camera object. */
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
surfaceView = (SurfaceView) findViewById(R.id.mysurface);
surfaceHolder = surfaceView.getHolder();
context = MainActivity.this;
if(context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CAMERA_FLASH)){
mTorch = (CompoundButton) findViewById(R.id.toggleButton1);
}
else{
// should use Dialog
// tell the user that he has no camera
//showDialog(context, FLASH_NOT_SUPPORTED);
}
final Camera mCamera = Camera.open(0);
mTorch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
Log.e("mTorch", "on");
Parameters camParams = mCamera.getParameters();
// params.setFlashMode( Parameters.FLASH_MODE_OFF )
camParams.setFlashMode( Parameters.FLASH_MODE_TORCH);
mCamera.setParameters(camParams);
mCamera.startPreview();
flashMode = camParams.getFlashMode();
Log.e("mTorch", flashMode );
// The toggle is enabled
} else {
// The toggle is disabled
Log.e("mTorch", "off");
Parameters camParams = mCamera.getParameters();
// params.setFlashMode( Parameters.FLASH_MODE_OFF )
camParams.setFlashMode( Parameters.FLASH_MODE_OFF);
mCamera.setParameters(camParams);
mCamera.stopPreview();
flashMode = camParams.getFlashMode();
Log.e("mTorch", flashMode );
}
}
});
//mCamera.release();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void onDestroy() {
super.onDestroy();
if (mCamera != null) {
camParams.setFlashMode(Parameters.FLASH_MODE_TORCH);
mCamera.setParameters(camParams);
mCamera.stopPreview();
mCamera.release();
}
}
}
The logging happily reports that the flashmode is torch or off as intended, however: The flash does not torch at all.
I read that I needed a surfaceview so I added it but with 0 height.
As I did collect bits and pieces here and there the code is probably not beautiful, my apologies.
Any idea on what I'm missing out?
(this is for a Nexus 5, 4.4.2)
Did you add permission to access camera in your manifest file?
uses-permission android:name="android.permission.CAMERA"
I have tried all the existing methods out there.. but everytime the application force closes. Here is the code. Please help me debugging it.
MainActivity.java
package com.example.camera1;
import android.os.Bundle;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.Toast;
public class MainActivity extends Activity {
private Camera cameraObject;
private ShowCamera showCamera;
private ImageView pic;
public static Camera isCameraAvailiable(){
Camera object = null;
try { object = Camera.open();
} catch (Exception e){
} return object;
}
private PictureCallback capturedIt = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
Bitmap bitmap = BitmapFactory.decodeByteArray(data , 0, data .length);
if(bitmap==null){
Toast.makeText(getApplicationContext(), "not taken", Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(getApplicationContext(), "taken", Toast.LENGTH_SHORT).show();
}
cameraObject.release();
}
};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pic = (ImageView)findViewById(R.id.imageView1);
cameraObject = isCameraAvailiable();
showCamera = new ShowCamera(this, cameraObject);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(showCamera);
}
public void snapIt(View view){
cameraObject.takePicture(null, null, capturedIt);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
ShowCamera.java
package com.example.camera1;
import java.io.IOException;
import android.content.Context;
import android.hardware.Camera;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class ShowCamera extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder holdMe;
private Camera theCamera;
public ShowCamera(Context context,Camera camera) {
super(context);
theCamera = camera;
holdMe = getHolder();
holdMe.addCallback(this);
// TODO Auto-generated constructor stub
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
try {
theCamera.setPreviewDisplay(holder);
theCamera.startPreview();
} catch (IOException e)
{
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<FrameLayout
android:id="#+id/camera_preview"
android:layout_width="fill_parent"
android:layout_height="199dp" >
</FrameLayout>
<Button
android:id="#+id/button_capture"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick = "snapIt"
android:text="#string/Capture"/>
<ImageView
android:id="#+id/imageView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="fitXY"
android:src="#drawable/ic_launcher"/>
</LinearLayout>
I am making this for android gingerbread and above versions. where my target sdk is Android Kitkat.
While testing the app on gingerbread it opens the application but simply shows a white screen that is it doesnt load the layout and force closes.. please help..!!
To open the camera,use the following code appropriately:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
Camera.CameraInfo info=new Camera.CameraInfo();
for (int i=0; i < Camera.getNumberOfCameras(); i++) {
Camera.getCameraInfo(i, info);
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
camera=Camera.open(i);
}
}
}
if (camera == null) {
camera=Camera.open();
}
Add the SurfaceView to a FrameLayout in order to display it.
Instead of returning the Camera,you could instead use the global Camera instance variable.The camera is released in onPause like this:
mCamera.release();
mCamera=null;
//remove SurfaceView from the FrameLayout you added it to
You can retain the Camera.Parameters object and use it to set the parameters to the value by placing a check in your surfaceChanged.
You could also consider starting your Camera in a seperate Thread in onCreate as it has been done here:
//This code is from AOSP ICS:
Thread mCameraOpenThread = new Thread(new Runnable() {
public void run() {
try {
mCameraDevice = Util.openCamera(Camera.this, mCameraId);
} catch (CameraHardwareException e) {
mOpenCameraFail = true;
} catch (CameraDisabledException e) {
mCameraDisabled = true;
}
}
});
This is the onCreate method:
super.onCreate(icicle);
mCameraOpenThread.start();
SurfaceView preview = (SurfaceView) findViewById(R.id.camera_preview);
SurfaceHolder holder = preview.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
// Make sure camera device is opened.
try {
mCameraOpenThread.join();
mCameraOpenThread = null;
}
catch(InterruptedException e)
{
//ignore
}
The link to the code is here http://android.googlesource.com/platform/packages/apps/Camera/+/ics-factoryrom-2-release/src/com/android/camera/Camera.java
I have yet to try this on an actual device, but expect similar results.
Anyway, long story short, whenever I run my app on the emulator, it crashes due to an out of memory exception.
My code really is essentially the same as the camera preview API demo from google, which runs perfectly fine.
The only file in the app (that I created/use) is as below-
package berbst.musicReader;
import java.io.IOException;
import android.app.Activity;
import android.content.Context;
import android.hardware.Camera;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
/*********************************
* Music Reader v.0001
* Still VERY under construction.
* #author Bryan
*
*********************************/
public class MusicReader extends Activity {
private MainScreen main;
#Override
//Begin activity
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
main = new MainScreen(this);
setContentView(main);
}
class MainScreen extends SurfaceView implements SurfaceHolder.Callback {
SurfaceHolder sHolder;
Camera cam;
MainScreen(Context context) {
super(context);
//Set up SurfaceHolder
sHolder = getHolder();
sHolder.addCallback(this);
sHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
// Open the camera and start viewing
cam = Camera.open();
try {
cam.setPreviewDisplay(holder);
} catch (IOException exception) {
cam.release();
cam = null;
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// Kill all our crap with the surface
cam.stopPreview();
cam.release();
cam = null;
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// Modify parameters to match size.
Camera.Parameters params = cam.getParameters();
params.setPreviewSize(w, h);
cam.setParameters(params);
cam.startPreview();
}
}
}
Make sure the camera permission is added in AndroidManifest.xml. Apparently you'll get an out of memory exception if you don't (for some bizarre reason). It worked for me, anyway.