I am capturing an image using the following code
public class PictureDemo extends Activity {
private SurfaceView preview=null;
private SurfaceHolder previewHolder=null;
private Camera camera=null;
private boolean inPreview=false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
save=(Button)findViewById(R.id.save);
save.setOnClickListener(this);
image=(ImageView)findViewById(R.id.image);
image.setImageResource(R.drawable.sofa);
preview=(SurfaceView)findViewById(R.id.preview);
previewHolder=preview.getHolder();
previewHolder.addCallback(surfaceCallback);
previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
public void onResume() {
super.onResume();
camera=CameraFinder.INSTANCE.open();
}
#Override
public void onPause() {
if (inPreview) {
camera.stopPreview();
}
camera.release();
camera=null;
inPreview=false;
super.onPause();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
new MenuInflater(this).inflate(R.menu.options, menu);
return(super.onCreateOptionsMenu(menu));
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId()==R.id.camera) {
if (inPreview) {
camera.takePicture(null, null, photoCallback);
inPreview=false;
}
return(true);
}
return(super.onOptionsItemSelected(item));
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode==KeyEvent.KEYCODE_CAMERA ||
keyCode==KeyEvent.KEYCODE_SEARCH) {
return(true);
}
return(super.onKeyDown(keyCode, event));
}
private Camera.Size getBestPreviewSize(int width, int height,
Camera.Parameters parameters) {
Camera.Size result=null;
for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
if (size.width<=width && size.height<=height) {
if (result==null) {
result=size;
}
else {
int resultArea=result.width*result.height;
int newArea=size.width*size.height;
if (newArea>resultArea) {
result=size;
}
}
}
}
return(result);
}
SurfaceHolder.Callback surfaceCallback=new SurfaceHolder.Callback() {
public void surfaceCreated(SurfaceHolder holder) {
try {
camera.setPreviewDisplay(previewHolder);
}
catch (Throwable t) {
Log.e("PictureDemo-surfaceCallback",
"Exception in setPreviewDisplay()", t);
Toast
.makeText(PictureDemo.this, t.getMessage(), Toast.LENGTH_LONG)
.show();
}
}
public void surfaceChanged(SurfaceHolder holder,
int format, int width,
int height) {
Camera.Parameters parameters=camera.getParameters();
Camera.Size size=getBestPreviewSize(width, height,
parameters);
if (size!=null) {
parameters.setPreviewSize(size.width, size.height);
parameters.setPictureFormat(PixelFormat.JPEG);
camera.setParameters(parameters);
camera.startPreview();
inPreview=true;
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// no-op
}
};
Camera.PictureCallback photoCallback=new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
new SavePhotoTask().execute(data);
camera.startPreview();
inPreview=true;
}
};
class SavePhotoTask extends AsyncTask<byte[], String, String> {
#Override
protected String doInBackground(byte[]... jpeg) {
File photo=new File(Environment.getExternalStorageDirectory(),
"photo.jpg");
if (photo.exists()) {
photo.delete();
}
try {
FileOutputStream fos=new FileOutputStream(photo.getPath());
fos.write(jpeg[0]);
fos.close();
}
catch (java.io.IOException e) {
Log.e("PictureDemo", "Exception in photoCallback", e);
}
return(null);
}
}
}
and the xml file is
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<android.view.SurfaceView
android:id="#+id/surface"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
<ImageView
android:id="#+id/image"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="matrix"
android:layout_centerInParent="true"
/>
<Button
android:id="#+id/save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="save"
android:layout_alignParentRight="true"
/>
</FrameLayout>
I can capture an image with this code but i need to add the image which was given to the ImageView to the captured image.
How to do that.
Thanks in advance.
Declare a Bitmap in your class
public class PictureDemo extends Activity {
Bitmap bitmap;
...
I think you can get the image you just took with this:
public void onPictureTaken(byte[] data, Camera camera) {
new SavePhotoTask().execute(data);
camera.startPreview();
inPreview=true;
bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
}
And then set the bitmap to your ImageView like this:
image.setImageBitmap(bitmap);
Trying doing something like this:
Bitmap bitmap = new Bitmap(define the size and other params you like).
Canvas canvas = new Canvas();
canvas.drawBitmap(your captured image);
canvas.drawBitmap(the overlay image);
// Now the bitmap will include both captured imaged and overlayed image
You can look in here and here
You can do mFrameLayout.getDrawingCache() to get a bitmap of the whole layout. The drawing cache should be enabled. I dont know its default state.
Related
I am in the process of using a simple camera preview as a background for one of my activities. My problem is that the camera preview is always landscape. I have the following and nothing seems to work.
Manifest file
android:configChanges="orientation"
Actitity_menu layout file
<LinearLayout
...
<SurfaceView
android:screenOrientation="portrait"
Menu Activity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
getWindow().setFormat(PixelFormat.UNKNOWN);
surfaceView = (SurfaceView)findViewById(R.id.camerapreview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
if(previewing){
camera.stopPreview();
previewing = false;
}
if (camera != null){
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
previewing = true;
} catch (IOException e) {
e.printStackTrace();
}
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
camera = Camera.open();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
camera.release();
camera = null;
previewing = false;
}
This is my XML file. I take one LinearLayout in which i take SurfaceView and Button, but camera displays view like following Image... look at Image and please give me solution.
<LinearLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical">
<SurfaceView
android:layout_height="match_parent"
android:layout_width="match_parent"
android:id="#+id/surface"
android:layout_weight="2"/>
<Button
android:layout_height="100dp"
android:layout_width="match_parent"
android:id="#+id/click"
android:text="Click Photo"
android:layout_weight="1"/>
</LinearLayout>
and here is my java code please check this also
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
clickphotobtn=(Button)findViewById(R.id.click);
surfaceview=(SurfaceView)findViewById(R.id.surface);
surfaceholder=surfaceview.getHolder();
surfaceholder.addCallback(this);
surfaceholder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
clickphotobtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//startActivity(intent);
camera.takePicture(null, null, null);
}
});
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
camera = Camera.open();
camera.setPreviewDisplay(surfaceholder);
// Toast.makeText(getApplication(), "Create", Toast.LENGTH_LONG).show();
} catch (IOException e) { }
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height)
{
Camera.Parameters parameters = camera.getParameters();
Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
if(display.getRotation()== Surface.ROTATION_0)
{
parameters.setPreviewSize(width, height);
camera.setDisplayOrientation(90);
}
if(display.getRotation()== Surface.ROTATION_90 || display.getRotation()== Surface.ROTATION_180)
parameters.setPreviewSize(width, height);
if(display.getRotation()==Surface.ROTATION_270)
{
parameters.setPreviewSize(width, height);
camera.setDisplayOrientation(180);
}
// camera.setParameters(parameters);
try{
camera.setPreviewDisplay(surfaceholder);
camera.startPreview();
}
catch (Exception e){
Toast.makeText(getApplication(), e.toString(), Toast.LENGTH_LONG).show();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (null == camera)
return;
camera.stopPreview();
camera.release();
camera = null;
preview = false;
//Toast.makeText(getApplication(), "Destroy", Toast.LENGTH_LONG).show();
}
This is the right way to change camera orientation, this piece of code worked for me. camera.setDisplayOrientation(90);
Try to follow the way suggested by the documentation, using Camera.CameraInfo in order to obtain the camera orientation and updating it consequently.
Look at the example here: void setDisplayOrientation(int).
Add
public class YourActivity extends AppCompatActivity implements SurfaceHolder.Callback{
....
}
I have written code to work with Custom Camera and for this I am using SurfaceView, now i want to know what if i need to implement Zoom IN and OUT functionality, I never worked on this kind of app.
My code, which i used to create Custom Camera, see below:
MainActivity.java:-
public class MainActivity extends Activity {
private SurfaceView preview=null;
private SurfaceHolder previewHolder=null;
public Camera camera ;
private boolean inPreview=false;
ImageButton btnCapture;
#SuppressWarnings("deprecation")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
preview=(SurfaceView)findViewById(R.id.surface);
previewHolder=preview.getHolder();
previewHolder.addCallback(surfaceCallback);
previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
previewHolder.setFixedSize(getWindow().getWindowManager()
.getDefaultDisplay().getWidth(), getWindow().getWindowManager()
.getDefaultDisplay().getHeight());
btnCapture = (ImageButton) findViewById(R.id.btnCapture);
btnCapture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(), "Capture Image(s)", Toast.LENGTH_LONG).show();
}
});
}
#Override
public void onResume() {
super.onResume();
camera=Camera.open();
}
#Override
public void onPause() {
super.onPause();
if (inPreview) {
camera.stopPreview(); }
camera.release();
camera=null;
inPreview=false;
}
private Camera.Size getBestPreviewSize(int width, int height,Camera.Parameters parameters){
Camera.Size result=null;
for (Camera.Size size : parameters.getSupportedPreviewSizes())
{
if (size.width<=width && size.height<=height)
{
if (result==null) {
result=size;
} else {
int resultArea=result.width*result.height;
int newArea=size.width*size.height;
if (newArea>resultArea) {
result=size;
}
}
}
}
return(result);
}
SurfaceHolder.Callback surfaceCallback=new SurfaceHolder.Callback(){
public void surfaceCreated(SurfaceHolder holder) {
try {
camera.setPreviewDisplay(previewHolder);
} catch (Throwable t) {
Log.e("PreviewDemo-surfaceCallback",
"Exception in setPreviewDisplay()", t);
Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_LONG).show();
}
}
public void surfaceChanged(SurfaceHolder holder,int format, int width,int height) {
Camera.Parameters parameters=camera.getParameters();
Camera.Size size=getBestPreviewSize(width, height,
parameters);
if (size!=null) {
parameters.setPreviewSize(size.width, size.height);
camera.setParameters(parameters);
camera.startPreview();
inPreview=true;
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
}
};
}
activity_main.xml:-
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/splash_background" >
<android.view.SurfaceView
android:id="#+id/surface"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<ImageButton
android:id="#+id/btnCapture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="#drawable/capture"
android:contentDescription="#string/app_name" />
</RelativeLayout>
I found a way by using several links, it works for me, and finally i have added code into my surfaceChanged(...), my complete surfaceChanged(..) code looks like, below:
declare variable of int datatype named currentZoomLevel and assign 0 as initial value,
int currentZoomLevel = 0;
Code:-
public void surfaceChanged(SurfaceHolder holder,int format, int width,int height) {
params = camera.getParameters();
params.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
Camera.Size size=getBestPreviewSize(width, height,
params);
if (size!=null) {
params.setPreviewSize(size.width, size.height);
camera.setParameters(params);
camera.startPreview();
inPreview=true;
ZoomControls zoomControls = (ZoomControls) findViewById(R.id.zoomControls);
if (params.isZoomSupported()) {
final int maxZoomLevel = params.getMaxZoom();
Log.i("max ZOOM ", "is " + maxZoomLevel);
zoomControls.setIsZoomInEnabled(true);
zoomControls.setIsZoomOutEnabled(true);
zoomControls.setOnZoomInClickListener(new OnClickListener(){
public void onClick(View v){
if(currentZoomLevel < maxZoomLevel){
currentZoomLevel++;
//mCamera.startSmoothZoom(currentZoomLevel);
params.setZoom(currentZoomLevel);
camera.setParameters(params);
}
}
});
zoomControls.setOnZoomOutClickListener(new OnClickListener(){
public void onClick(View v){
if(currentZoomLevel > 0){
currentZoomLevel--;
params.setZoom(currentZoomLevel);
camera.setParameters(params);
}
}
});
}
else
zoomControls.setVisibility(View.GONE);
}
}
Xml:-
<ZoomControls
android:id="#+id/zoomControls"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true" />
I am placing my answer, just for more clearity and for viewers future use..
Below is the sample code for zoom functionality .Please try if it can help you:
public class DemoActivity extends Activity {
private FrameLayout pCameraLayout = null; // this layout contains surfaceview
private ZoomControls zoomControls ;
Camera mCamera=null;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
enableZoom();
}
private void enableZoom() {
zoomControls = new ZoomControls(this);
zoomControls.setIsZoomInEnabled(true);
zoomControls.setIsZoomOutEnabled(true);
zoomControls.setOnZoomInClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
zoomCamera(false);
}
});
zoomControls.setOnZoomOutClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
zoomCamera(true);
}
});
pCameraLayout.addView(zoomControls);
}
/**
* Enables zoom feature in native camera . Called from listener of the view
* used for zoom in and zoom out.
*
*
* #param zoomInOrOut "false" for zoom in and "true" for zoom out
*/
public void zoomCamera(boolean zoomInOrOut) {
if(mCamera!=null) {
Parameters parameter = mCamera.getParameters();
if(parameter.isZoomSupported()) {
int MAX_ZOOM = parameter.getMaxZoom();
int currnetZoom = parameter.getZoom();
if(zoomInOrOut && (currnetZoom <MAX_ZOOM && currnetZoom >=0)) {
parameter.setZoom(++currnetZoom);
}
else if(!zoomInOrOut && (currnetZoom <=MAX_ZOOM && currnetZoom >0)) {
parameter.setZoom(--currnetZoom);
}
}
else
Toast.makeText(context, "Zoom Not Avaliable", Toast.LENGTH_LONG).show();
mCamera.setParameters(parameter);
}
}
I was trying to write a simple camera app, but I ran into quite a frustrating problem with my picture preview. It shows horizontal flicker lines running up the screen. My screen has a width of 800 (Galaxy SII plus), so there are black spaces on the edges (the activity is set to horizontal orientation). Now these black margins begin to transition to a white-grey at the bottom ends when the flicker occurs, so I suspect there might be something drawn over them.
The really annoying part is that this does not seem to depend on the actual code, since it sometimes works without any flickering.
public class Preview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera camera;
private Point size;
Preview(Context context, Camera camera, Point size) {
super(context);
this.camera = camera;
this.size = size;
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
setWillNotDraw(false);
Parameters parameters = camera.getParameters();
parameters.setPreviewSize(720, 480);
parameters.setPictureSize(720, 480);
camera.setParameters(parameters);
Camera.Size previewSize = camera.getParameters().getPreviewSize();
setLayoutParams(new FrameLayout.LayoutParams(previewSize.width,
previewSize.height, Gravity.CENTER));
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
if (mHolder.getSurface() == null) {
return;
}
// stop preview before making changes
try {
camera.stopPreview();
} catch (Exception e) {
}
Camera.Size previewSize = camera.getParameters().getPreviewSize();
setLayoutParams(new FrameLayout.LayoutParams(previewSize.width,
previewSize.height, Gravity.CENTER));
try {
camera.setPreviewDisplay(mHolder);
camera.startPreview();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
camera.setPreviewDisplay(holder);
camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder arg0) {
}
#Override
protected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) {
}
public void setCamera(Camera camera) {
if (this.camera == camera) {
return;
}
stopPreviewAndFreeCamera();
this.camera = camera;
if (this.camera != null) {
requestLayout();
try {
this.camera.setPreviewDisplay(mHolder);
} catch (IOException e) {
e.printStackTrace();
}
this.camera.startPreview();
}
}
public void stopPreviewAndFreeCamera() {
if (this.camera != null) {
this.camera.stopPreview();
this.camera.release();
this.camera = null;
}
}
public void takePicture() {
camera.autoFocus(null);
camera.takePicture(null, null, new PictureHandler(this.getContext()));
camera.startPreview();
}
}
public class MainActivity extends Activity {
private Preview mPreview;
.
.
.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK)) {
this.mPreview.stopPreviewAndFreeCamera();
finish();
}
return super.onKeyDown(keyCode, event);
}
}
public class PreviewDemo extends Activity {
private SurfaceView preview=null;
private SurfaceHolder previewHolder=null;
private Camera camera=null;
private boolean inPreview=false;
private boolean cameraConfigured=false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
preview=(SurfaceView)findViewById(R.id.preview);
previewHolder=preview.getHolder();
previewHolder.addCallback(surfaceCallback);
previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
public void onResume() {
super.onResume();
camera=Camera.open();
startPreview();
}
#Override
public void onPause() {
if (inPreview) {
camera.stopPreview();
}
camera.release();
camera=null;
inPreview=false;
super.onPause();
}
private Camera.Size getBestPreviewSize(int width, int height,
Camera.Parameters parameters) {
Camera.Size result=null;
for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
if (size.width<=width && size.height<=height) {
if (result==null) {
result=size;
}
else {
int resultArea=result.width*result.height;
int newArea=size.width*size.height;
if (newArea>resultArea) {
result=size;
}
}
}
}
return(result);
}
private void initPreview(int width, int height) {
if (camera!=null && previewHolder.getSurface()!=null) {
try {
camera.setPreviewDisplay(previewHolder);
}
catch (Throwable t) {
Log.e("PreviewDemo-surfaceCallback",
"Exception in setPreviewDisplay()", t);
Toast
.makeText(PreviewDemo.this, t.getMessage(), Toast.LENGTH_LONG)
.show();
}
if (!cameraConfigured) {
Camera.Parameters parameters=camera.getParameters();
Camera.Size size=getBestPreviewSize(width, height,
parameters);
if (size!=null) {
parameters.setPreviewSize(size.width, size.height);
camera.setParameters(parameters);
cameraConfigured=true;
}
}
}
}
private void startPreview() {
if (cameraConfigured && camera!=null) {
camera.startPreview();
inPreview=true;
}
}
SurfaceHolder.Callback surfaceCallback=new SurfaceHolder.Callback() {
public void surfaceCreated(SurfaceHolder holder) {
// no-op -- wait until surfaceChanged()
}
public void surfaceChanged(SurfaceHolder holder,
int format, int width,
int height) {
initPreview(width, height);
startPreview();
}
public void surfaceDestroyed(SurfaceHolder holder) {
// no-op
}
};
}
The above code is working fine for when i launch the application the camera preview is displayed with no actions performed in that. But i want to get an image overlay on the live feed camera. please help me.....
I will give you a hint, if you are still stuck. In your layout definition you can define a frame layout or a relative layout in a way that the views are or apear to be on top of each other. You can see an example here:
http://littlesaiph.blogspot.de/2011/07/getting-images-laid-pause-over-video-in.html