Its the first time i have used surface view and surface holder with a very rough knowledge of both, the live image preview in the surfaceview is skewed and rotated, on searching i found out i need to set CameraParameter but i could understand how it works and also is there any guide to understanding the Camera2 api
public class CamActivity extends AppCompatActivity implements SurfaceHolder.Callback{
Camera mCamera;
SurfaceView surfaceView;
private SurfaceHolder mHolder;
FloatingActionButton cam;
private static final int pRequestCode = 5002;
private static final String[] mPermissions = {Manifest.permission.CAMERA, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.RECORD_AUDIO, Manifest.permission.WRITE_EXTERNAL_STORAGE};
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.cam_layout);
checkCameraHardware();
checkPermissions();
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
surfaceView = (SurfaceView) findViewById(R.id.camera_preview);
mHolder = surfaceView.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
cam = (FloatingActionButton) findViewById(R.id.fabCamera);
cam.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mCamera.takePicture(null, null, mPicture);
}
}
);
}
private boolean checkCameraHardware() {
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
// this device has a camera
return true;
} else {
// no camera on this device
return false;
}
}
private void checkPermissions() {
if (ContextCompat.checkSelfPermission(this, mPermissions[0]) != PackageManager.PERMISSION_GRANTED
||ContextCompat.checkSelfPermission(this, mPermissions[1]) != PackageManager.PERMISSION_GRANTED
||ContextCompat.checkSelfPermission(this, mPermissions[2]) != PackageManager.PERMISSION_GRANTED
||ContextCompat.checkSelfPermission(this, mPermissions[3]) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, mPermissions, pRequestCode);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case pRequestCode: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this,"Camera Allowed",Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this,"Camera Denied",Toast.LENGTH_SHORT).show();
}
if (grantResults.length > 0 && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this,"Location Allowed",Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this,"Location Denied",Toast.LENGTH_SHORT).show();
}
if (grantResults.length > 0 && grantResults[2] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this,"Microphone Allowed",Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this,"Microphone Denied",Toast.LENGTH_SHORT).show();
}
if (grantResults.length > 0 && grantResults[3] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this,"Storage Allowed",Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this,"Storage Denied",Toast.LENGTH_SHORT).show();
}
return;
}
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera = Camera.open();
}
catch (Exception e){
}
Camera.Parameters parameters = mCamera.getParameters();
parameters.set("orientation", "portrait");
mCamera.setParameters(parameters);
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
try {
mCamera.stopPreview();
} catch (Exception e){
}
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
private Camera.PictureCallback mPicture = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
Log.d("", "Error creating media file, check storage permissions: " );
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d("", "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d("", "Error accessing file: " + e.getMessage());
}
}
};
private static File getOutputMediaFile(int type){
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES), "MyCameraApp");
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_"+ timeStamp + ".jpg");
} else if(type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "VID_"+ timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
}
For Camera2 API you can check Android code sample from Android Studio or GitHub.
You can solve camera preview rotation and aspect ratio in surfaceCreated() like this. Note that you'll have to properly deal with the exceptions:
#Override
public void surfaceCreated(SurfaceHolder holder) {
// You need to open the camera in a
// different manner so you can obtain some info from it
int numberOfCameras = Camera.getNumberOfCameras();
Camera.CameraInfo info = new Camera.CameraInfo();
mCamera = null;
for (int i = 0; i < numberOfCameras; i++) {
Camera.getCameraInfo(i, info);
// Open a back camera
if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
try {
mCamera = Camera.open(i);
break;
} catch (RuntimeException e) {
// Could not open camera
}
}
}
if (mCamera == null) {
// No camera found
}
Camera.Parameters parameters = mCamera.getParameters();
// Rotate display
// Code from here:
// https://developer.android.com/reference/android/hardware/Camera.html#setDisplayOrientation(int)
int rotation = activity.getWindowManager().getDefaultDisplay()
.getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0: degrees = 0; break;
case Surface.ROTATION_90: degrees = 90; break;
case Surface.ROTATION_180: degrees = 180; break;
case Surface.ROTATION_270: degrees = 270; break;
}
int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
result = (info.orientation - degrees + 360) % 360;
}
mCamera.setDisplayOrientation(result);
Camera.Size size = parameters.getPreviewSize();
// You'll probably want to set the preview
// width and height to match the preview size
// aspect ratio that you can obtain by:
// (double) size.width / (double) size.height
//
// Note that if the int result above modulo 180
// equals 90, you'll have to exchange width for height
// and vice versa.
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
Related
I'm creating android camera app. This is an custom camera using camera API.
Whenever I take picture from camera it always save in landscap mode.
I'm using this method to set the camera orientation.
public static void setCameraDisplayOrientation(Activity activity,
int cameraId, android.hardware.Camera camera) {
android.hardware.Camera.CameraInfo info =
new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId, info);
int rotation = activity.getWindowManager().getDefaultDisplay()
.getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0: degrees = 0; break;
case Surface.ROTATION_90: degrees = 90; break;
case Surface.ROTATION_180: degrees = 180; break;
case Surface.ROTATION_270: degrees = 270; break;
}
int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
result = (info.orientation - degrees + 360) % 360;
}
camera.setDisplayOrientation(result);
}
Here is code which is responsible to store image.
PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
Log.d(TAG, "Error creating media file, check storage permissions: ");
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
};
This code save the image successfully but always in landscape mode. What I'm missing I'm new in android. I want to save image as like it is shown in preview.
Update 2 (According To Answer)
PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
Camera.CameraInfo info = new Camera.CameraInfo();
int rotationAngle = getCorrectCameraOrientation (MainActivity.this, info);
Toast.makeText(MainActivity.this, "Angle "+ rotationAngle, Toast.LENGTH_SHORT).show();
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
try {
writeFile (data, pictureFile);
} catch (IOException e) {
e.printStackTrace();
}
processImage (pictureFile, rotationAngle, 1);
}
};
I'm using code in this way but this is not working still same problem image is always in landscape mode.
Try
1. First of all, add methods (writeFile, processImage and getCorrectCameraOrientation) defined below (After step 3)
2. Calculate camera orientation after capturing photo and update onPictureTaken**
#Override
public void onPictureTaken (final byte[] data, final Camera camera) {
int rotationAngle = getCorrectCameraOrientation (this, info);
3. Create file and update photo angle using rotationAngle
File file = new File (folder, fileName);
try {
file.createNewFile ();
}
catch (IOException e) {
e.printStackTrace ();
}
writeFile (data, file);
processImage (file, rotationAngle, compressRatio);
writeFile
public static void writeFile (byte[] data, File file) throws IOException {
BufferedOutputStream bos = null;
try {
FileOutputStream fos = new FileOutputStream (file);
bos = new BufferedOutputStream (fos);
bos.write (data);
}
finally {
if (bos != null) {
try {
bos.flush ();
bos.close ();
}
catch (Exception e) {
}
}
}
}
processImage
public static void processImage (File file, int rotationAngle, int compressionRatio) {
BufferedOutputStream bos = null;
try {
Bitmap bmp = BitmapFactory.decodeFile (file.getPath ());
Matrix matrix = new Matrix ();
matrix.postRotate (rotationAngle);
bmp = Bitmap.createBitmap (bmp, 0, 0, bmp.getWidth (), bmp.getHeight (), matrix, true);
FileOutputStream fos = new FileOutputStream (file);
bmp.compress (Bitmap.CompressFormat.PNG, compressionRatio, fos);
}
catch (IOException e) {
e.printStackTrace ();
}
catch (OutOfMemoryError t) {
t.printStackTrace ();
}
catch (Throwable t) {
t.printStackTrace ();
}
finally {
if (bos != null) {
try {
bos.flush ();
bos.close ();
}
catch (Exception e) {
}
}
}
}
getCorrectCameraOrientation
public static int getCorrectCameraOrientation (Activity activity, Camera.CameraInfo info) {
int rotation = activity.getWindowManager ().getDefaultDisplay ().getRotation ();
int degrees = 0;
if (hasValidRotation (rotation)) {
degrees = rotation * 90;
}
int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360;
}
else {
result = (info.orientation - degrees + 360) % 360;
}
return result;
}
The following code works fine in android version less than lollipop but in lollipop and above version its not working. Can Anybody help what to do so that it can work in all the versions. I have tested it in many devices, but in lollipop im getting this error "takePicture failed".
public class CameraService extends Service {
private Camera camera;
private int cameraId = 0;
private Timer timer;
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onStart(Intent intent, int startId) {
capureImage();
super.onStart(intent, startId);
}
public void capureImage() {
try {
cameraId = findFrontFacingCamera();
if (cameraId < 0) {
} else {
SurfaceView view = new SurfaceView(getApplicationContext());
safeCameraOpen(cameraId);
camera.setPreviewDisplay(view.getHolder());
camera.startPreview();
Camera.Parameters params = camera.getParameters();
params.setJpegQuality(100);
camera.setParameters(params);
camera.takePicture(null, null, mCall);
}
} catch (IOException e) {
e.printStackTrace();
}
}
Camera.PictureCallback mCall = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
try {
Bitmap bitmapPicture = BitmapFactory.decodeByteArray(data, 0,
data.length);
saveBitmap(bitmapPicture);
releaseCamera();
} catch (Exception e) {
e.printStackTrace();
Log.e("exception", e.getMessage());
}
}
};
private void saveBitmap(Bitmap bmp) {
String _time = "";
Calendar cal = Calendar.getInstance();
int millisecond = cal.get(Calendar.MILLISECOND);
int second = cal.get(Calendar.SECOND);
int minute = cal.get(Calendar.MINUTE);
int hourofday = cal.get(Calendar.HOUR_OF_DAY);
_time = "image_" + hourofday + "" + minute + "" + second + ""
+ millisecond;
String file_path = Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/DiaryFakeImage";
try {
File dir = new File(file_path);
if (!dir.exists())
dir.mkdirs();
File file = new File(dir, _time);
FileOutputStream fOut = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.PNG, 90, fOut);
fOut.flush();
fOut.close();
} catch (Exception e) {
Log.e("error in saving image", e.getMessage());
}
}
private boolean safeCameraOpen(int id) {
boolean qOpened = false;
try {
releaseCamera();
camera = Camera.open(id);
qOpened = (camera != null);
} catch (Exception e) {
e.printStackTrace();
}
return qOpened;
}
private void releaseCamera() {
if (camera != null) {
camera.stopPreview();
camera.release();
camera = null;
}
}
private int findFrontFacingCamera() {
int cameraId = -1;
int numberOfCameras = Camera.getNumberOfCameras();
for (int i = 0; i < numberOfCameras; i++) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(i, info);
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
cameraId = i;
break;
}
}
return cameraId;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
You need to use SurfaceTexture for Lollipop.
Try adding this just before camera.startPreview();-
SurfaceTexture st = new SurfaceTexture(MODE_PRIVATE);
camera.setPreviewTexture(st);
camera.startPreview();
i'm working on a android application and I have to take a picture and save it. It's working and my picture is saved in a directory of the phone. Especially, in Picture directory.
So, here its my class parameter with the button to launch the camera ( new activity) and take the picture :
public class Parametre extends Activity {
private EditText ETpseudo= null;
private Button buttonPhoto = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.parametres);
ETpseudo =(EditText) findViewById(R.id.editPseudo);
buttonPhoto = (Button) findViewById(R.id.buttonPhoto);
//ivPhoto.setImageBitmap();
buttonPhoto.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(Parametre.this, CameraActivity.class));
}
});
}
}
CameraActivity :
public class CameraActivity extends Activity {
private Camera mCamera;
private CameraPreview mCameraPreview;
private ImageView cadrePhoto = null;
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
Log.d("DEBUG", String.valueOf(grantResults[0]));
startCamera();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera);
Button captureButton = (Button) findViewById(R.id.button_capture);
startCamera();
captureButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mCamera.takePicture(null, null, mPicture);
}
});
}
private void startCamera(){
mCamera = getCameraInstance();
mCamera.startPreview();
mCameraPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mCameraPreview);
setCameraDisplayOrientation(this, 1, mCamera);
}
/**
* Helper method to access the camera returns null if it cannot get the
* camera or does not exist
*
* #return
*/
#TargetApi(Build.VERSION_CODES.GINGERBREAD)
private Camera getCameraInstance() {
Camera camera = null;
try {
camera = Camera.open(1);
} catch (Exception e) {
e.printStackTrace();
}
return camera;
}
#TargetApi(Build.VERSION_CODES.GINGERBREAD)
public void setCameraDisplayOrientation(Activity activity, int cameraId,android.hardware.Camera camera) {
android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId, info);
int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0:
degrees = 0;
break;
case Surface.ROTATION_90:
degrees = 90;
break;
case Surface.ROTATION_180:
degrees = 180;
break;
case Surface.ROTATION_270:
degrees = 270;
break;
}
int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
result = (info.orientation - degrees + 360) % 360;
}
camera.setDisplayOrientation(result);
}
Camera.PictureCallback mPicture = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
Log.d("Error", "Error creating media file, check storage permissions: ");
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d("DBG", "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d("Error", "Error accessing file: " + e.getMessage());
}
}
};
private static File getOutputMediaFile() {
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "MyCameraApp");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
return mediaFile;
}
}
So, after taking the photo, I want to display the image on an ImageView in the parameter view. But I dont know how to do this. How to get back the photo and display him on the parameter View ?
Thanks.
Sorry for my english :/
you can do this in as easy way just create an static bitmap when picture taken in picturecallback method
Bitmap bmap=BitmapFactory.decodeByteArray(data, 0, data.length,sizeOptions);
Log.e("clickedbitmaaapp", String.valueOf(bmap));
static Bitmap mBitmap=bmap;
create this bitmap in other class which where you can access this easily.
Thanks you.
I can't test my code now. But do you think that should work here ? :
(cameraActivity)
public class CameraActivity extends Activity {
static Bitmap mBitmap;
...
Camera.PictureCallback mPicture = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
Log.d("Error", "Error creating media file, check storage permissions: ");
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
BitmapFactory.Options options = new BitmapFactory.Options();
Bitmap bmap= BitmapFactory.decodeByteArray(data, 0, data.length, options);
mBitmap = bmap;
} catch (FileNotFoundException e) {
Log.d("DBG", "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d("Error", "Error accessing file: " + e.getMessage());
}
}
};
and then in my parameter class :
public class Parametre extends Activity {
private EditText ETpseudo= null;
private Button buttonPhoto = null;
private ImageView iv = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.parametres);
ETpseudo =(EditText) findViewById(R.id.editPseudo);
buttonPhoto = (Button) findViewById(R.id.buttonPhoto);
//ivPhoto.setImageBitmap();
buttonPhoto.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(Parametre.this, CameraActivity.class));
}
});
ImageView imageView=(ImageView)findViewById(R.id.cadreImage);
imageView.setImageBitmap(CameraActivity.mBitmap);
}
}
I am new to android. I just downloaded an example camera program. I can take one image each time I click the "capture" button.
Now I want to know if it is possible to take two images continuously (one with flash and one without flash). Does anybody have a hint on how to do that? Thanks a lot.
I posted the sample code here:
public class AndroidCameraExample extends Activity {
private Camera mCamera;
private CameraPreview mPreview;
private PictureCallback mPicture;
private Button capture, switchCamera;
private Context myContext;
private LinearLayout cameraPreview;
private boolean cameraFront = false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
myContext = this;
initialize();
}
private int findFrontFacingCamera() {
int cameraId = -1;
// Search for the front facing camera
int numberOfCameras = Camera.getNumberOfCameras();
for (int i = 0; i < numberOfCameras; i++) {
CameraInfo info = new CameraInfo();
Camera.getCameraInfo(i, info);
if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
cameraId = i;
cameraFront = true;
break;
}
}
return cameraId;
}
private int findBackFacingCamera() {
int cameraId = -1;
//Search for the back facing camera
//get the number of cameras
int numberOfCameras = Camera.getNumberOfCameras();
//for every camera check
for (int i = 0; i < numberOfCameras; i++) {
CameraInfo info = new CameraInfo();
Camera.getCameraInfo(i, info);
if (info.facing == CameraInfo.CAMERA_FACING_BACK) {
cameraId = i;
cameraFront = false;
break;
}
}
return cameraId;
}
public void onResume() {
super.onResume();
if (!hasCamera(myContext)) {
Toast toast = Toast.makeText(myContext, "Sorry, your phone does not have a camera!", Toast.LENGTH_LONG);
toast.show();
finish();
}
if (mCamera == null) {
//if the front facing camera does not exist
if (findFrontFacingCamera() < 0) {
Toast.makeText(this, "No front facing camera found.", Toast.LENGTH_LONG).show();
switchCamera.setVisibility(View.GONE);
}
mCamera = Camera.open(findBackFacingCamera());
mPicture = getPictureCallback();
mPreview.refreshCamera(mCamera);
}
}
public void initialize() {
cameraPreview = (LinearLayout) findViewById(R.id.camera_preview);
mPreview = new CameraPreview(myContext, mCamera);
cameraPreview.addView(mPreview);
capture = (Button) findViewById(R.id.button_capture);
capture.setOnClickListener(captrureListener);
switchCamera = (Button) findViewById(R.id.button_ChangeCamera);
switchCamera.setOnClickListener(switchCameraListener);
}
OnClickListener switchCameraListener = new OnClickListener() {
#Override
public void onClick(View v) {
//get the number of cameras
int camerasNumber = Camera.getNumberOfCameras();
if (camerasNumber > 1) {
//release the old camera instance
//switch camera, from the front and the back and vice versa
releaseCamera();
chooseCamera();
} else {
Toast toast = Toast.makeText(myContext, "Sorry, your phone has only one camera!", Toast.LENGTH_LONG);
toast.show();
}
}
};
public void chooseCamera() {
//if the camera preview is the front
if (cameraFront) {
int cameraId = findBackFacingCamera();
if (cameraId >= 0) {
//open the backFacingCamera
//set a picture callback
//refresh the preview
mCamera = Camera.open(cameraId);
mPicture = getPictureCallback();
mPreview.refreshCamera(mCamera);
}
} else {
int cameraId = findFrontFacingCamera();
if (cameraId >= 0) {
//open the backFacingCamera
//set a picture callback
//refresh the preview
mCamera = Camera.open(cameraId);
mPicture = getPictureCallback();
mPreview.refreshCamera(mCamera);
}
}
}
#Override
protected void onPause() {
super.onPause();
//when on Pause, release camera in order to be used from other applications
releaseCamera();
}
private boolean hasCamera(Context context) {
//check if the device has camera
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
return true;
} else {
return false;
}
}
private PictureCallback getPictureCallback() {
PictureCallback picture = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
//make a new picture file
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
return;
}
try {
//write the file
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
Toast toast = Toast.makeText(myContext, "Picture saved: " + pictureFile.getName(), Toast.LENGTH_LONG);
toast.show();
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
//refresh camera to continue preview
mPreview.refreshCamera(mCamera);
}
};
return picture;
}
OnClickListener captrureListener = new OnClickListener() {
#Override
public void onClick(View v) {
Camera.Parameters parameters = mCamera.getParameters();
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
mCamera.setParameters(parameters);
mCamera.takePicture(null, null, mPicture);
}
};
//make picture and save to a folder
private static File getOutputMediaFile() {
//make a new file directory inside the "sdcard" folder
File mediaStorageDir = new File("/sdcard/", "JCG Camera");
//if this "JCGCamera folder does not exist
if (!mediaStorageDir.exists()) {
//if you cannot make this folder return
if (!mediaStorageDir.mkdirs()) {
return null;
}
}
//take the current timeStamp
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
//and make a media file:
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
return mediaFile;
}
private void releaseCamera() {
// stop and release camera
if (mCamera != null) {
mCamera.release();
mCamera = null;
}
}
}
I'm using the Surfaceholder and the camera to capture an image but when I do it on my HTC Desire S the captured image looks like this. This is not what it looks like in the preview-view.
It works on two of the other phones I have been testing on so it should be a device dependant issue but I can't figure out what.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_camera_overlay);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().setFormat(PixelFormat.UNKNOWN);
surfaceView = (SurfaceView)findViewById(R.id.camerapreview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
controlInflater = LayoutInflater.from(getBaseContext());
View viewControl = controlInflater.inflate(R.layout.overlay, null);
LayoutParams layoutParamsControl
= new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT);
this.addContentView(viewControl, layoutParamsControl);
Button buttonTakePicture = (Button)findViewById(R.id.takepicture);
buttonTakePicture.setOnClickListener(new Button.OnClickListener(){
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
camera.takePicture(myShutterCallback,
myPictureCallback_RAW, myPictureCallback_JPG);
}});
}
...
PictureCallback myPictureCallback_JPG = new PictureCallback(){
#Override
public void onPictureTaken(byte[] byteArray, Camera arg1) {
//Uri uriTarget = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, new ContentValues());
OutputStream imageFileOS;
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddhhmmss");
String date = dateFormat.format(new Date());
String _path = Environment.getExternalStorageDirectory() + File.separator + "xxx" + File.separator + "Livboj" + date + ".jpg";
File file = new File( _path );
Uri uriTarget = Uri.fromFile( file );
try {
imageFileOS = getContentResolver().openOutputStream(uriTarget);
imageFileOS.write(byteArray);
imageFileOS.flush();
imageFileOS.close();
Toast.makeText(CameraOverlayActivity.this,"Image saved: " + uriTarget.toString(),Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
camera.startPreview();
}};
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
if(previewing){
camera.stopPreview();
previewing = false;
}
Parameters parameters = camera.getParameters();
Camera.Size size = getBestPreviewSize(width, height);
parameters.setPreviewSize(size.width, size.height);
Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
if(display.getRotation() == Surface.ROTATION_0)
{
camera.setDisplayOrientation(90);
}
if(display.getRotation() == Surface.ROTATION_90)
{
}
if(display.getRotation() == Surface.ROTATION_180)
{
}
if(display.getRotation() == Surface.ROTATION_270)
{
camera.setDisplayOrientation(180);
}
camera.setParameters(parameters);
previewCamera();
}
private Camera.Size getBestPreviewSize(int width, int height)
{
Camera.Size result=null;
Camera.Parameters p = camera.getParameters();
for (Camera.Size size : p.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;
}
public void previewCamera()
{
try
{
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
previewing = true;
}
catch(Exception e)
{
Log.d("Camera", "Cannot start preview", e);
}
}
I don't know it the problem is in the saving or in the capturing. Has anyone encountered the same problem? Thanks in advance!