I'm making an application that implements the Camera, and I was wondering why does the image get saved to a tiny bitmap when I take a picture?
When I press the capture button, for some reason the image gets scaled down (I need to save the image to INTERNAL memory, not external/sd card) and I end up having to scale it back up to display it in the ImageView, which obviously makes the photo a little bit more grainy than the camera preview is. Is there a better way to do this?
I want it to be similar to SnapChat, where the picture you take is displayed exactly how it looked when you took it...
Here's the main Activity:
public class MainActivity extends FragmentActivity {
private static final String TAG = "CameraActivity";
public static final int MEDIA_TYPE_IMAGE = 1;
private Camera mCamera;
private CameraPreview mPreview;
private Context mContext;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
if(checkCameraHardware(mContext)){
// Create an instance of Camera
mCamera = getCameraInstance();
// Create our Preview view and set it as the content of our activity.
mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview);
// Add a listener to the Capture button
Button captureButton = (Button) findViewById(R.id.button_capture);
captureButton.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
// get an image from the camera
mCamera.takePicture(null, null, mPicture);
}
}
);
}
}
private Camera.PictureCallback mPicture = new Camera.PictureCallback() {
#Override
public void onPictureTaken(final byte[] data, Camera camera) {
new AsyncTask<Void, Void, String>() {
#Override
protected String doInBackground(Void... params) {
try {
FileOutputStream fos = openFileOutput("img.jpg", Context.MODE_PRIVATE);
fos.write(data);
fos.close();
return "img.jpg";
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
return null;
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
return null;
}
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if(result != null){
Intent intent = new Intent(mContext, ImageDisplayActivity.class);
intent.putExtra(ImageDisplayActivity.KEY_PATH, "img.jpg");
startActivity(intent);
}
}
}.execute();
}
};
private boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
// this device has a camera
return true;
} else {
// no camera on this device
return false;
}
}
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
}
/** Create a File for saving an image or video */
}
And here's the Image Display Activity:
public class ImageDisplayActivity extends FragmentActivity {
public static final String KEY_PATH = "img.jpg";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_display);
Intent intent = getIntent();
String path = getIntent().getStringExtra(ImageDisplayActivity.KEY_PATH);
try {
java.io.FileInputStream in = this.openFileInput(path);
Bitmap bitmap = BitmapFactory.decodeStream(in);
ZoomInZoomOut touch = (ZoomInZoomOut)findViewById(R.id.IMAGEID);
touch = arrangeImageView(touch);
touch.setImageBitmap(bitmap);
in.close();
Canvas c = new Canvas(bitmap);
} catch (Exception e) {
e.printStackTrace();
}
}
private ZoomInZoomOut arrangeImageView(ZoomInZoomOut img){
try {
img.setRotation(90);
img.setScaleX(2f);
img.setScaleY(2f);
} catch (Exception e) {
e.printStackTrace();
}
return img;
}
}
Related
I need to access asynctask output in another activity .Drawable which is returned in loadImageAsyntask, I need to use it in SpecificActivity class for setting imageview....I have tried but getting null value in specific activity class.Also while moving back from specific activity using back navigation, previous activity is loading again.In previous activity Im doing fetching data through url by parsing json. So when Im clicking back to previous activity, again data is fetching process gets started. I need to avoid loading again instead I need to show the previously loaded data.
public class LoadImageAsyncTask extends AsyncTask<String, Void, Drawable> {
private Drawable drawable;
String imageUrl;
private Drawable image;
#Override
protected Drawable doInBackground(String... strings) {
try {
InputStream is = (InputStream) new URL(imageUrl).getContent();
Drawable d = Drawable.createFromStream(is, "src name");
Log.e("drwable",""+d);
} catch (Exception e) {
Log.e("Specific Activity", "Converting drawable" + e);
}
return drawable;
}
#Override
protected void onPostExecute(Drawable drawableImage) {
super.onPostExecute(drawableImage);
setImage(drawableImage);
}
public void setImage(Drawable drawable)
{
new SpecificNewsReportActivity().drawable=drawable;
Log.e("set image",""+drawable);
this.drawable=drawable;
}
public Drawable getImage()
{
Log.e("get image",""+drawable);
return drawable;
}
}
public class SpecificNewsReportActivity extends AppCompatActivity {
private TextView contentTextView, titleTextView;
public ImageView imageView;
private Intent intent;
public Drawable drawable;
private String imageUrl;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_specific_news_report);
ActionBar actionBar=this.getSupportActionBar();
if(actionBar!=null)
{
actionBar.setDisplayHomeAsUpEnabled(true);
}
intent = getIntent();
LoadImageAsyncTask task = new LoadImageAsyncTask();
AsyncTask<String, Void, Drawable> d=task.execute();
try {
drawable = d.get();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
imageUrl = getIntent().getStringExtra("image");
Log.e("drawable specific", "" + drawable);
drawable=new LoadImageAsyncTask().getImage();
contentTextView = (TextView) findViewById(R.id.specific_news_report_content_text_view);
titleTextView = (TextView) findViewById(R.id.specific_news_report_title_text_view);
imageView = (ImageView) findViewById(R.id.specific_news_report_image_view);
contentTextView.setText(intent.getStringExtra("content"));
titleTextView.setText(intent.getStringExtra("title"));
try {
if(drawable!=null) {
imageView.setImageDrawable(drawable);
}
else
{
Log.e("returned drawable","null");
}
} catch (Exception ex) {
Log.e(" exception", "" + ex);
}
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home){
Intent intent = NavUtils.getParentActivityIntent(this);
NavUtils.navigateUpTo(this, intent);
}
return super.onOptionsItemSelected(item);
}
}
I want to create an application to take a picture. I followed the Camera tutorial, I tried 3 times but unable to make it work.I added a button to take a picture.But the app is not working properly.Please help me out.Here is my code:
// CAMERA VIEW displays the picture in a FrameLayout
public class CameraView extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraView(Context context, Camera camera){
super(context);
mCamera = camera;
mCamera.setDisplayOrientation(0);
//get the holder and set this class as the callback, so we can get camera data here
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_NORMAL);
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
try{
//when the surface is created, we can set the camera to draw images in this surfaceholder
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
} catch (IOException e) {
Log.d("ERROR", "Camera error on surfaceCreated " + e.getMessage());
}
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) {
//before changing the application orientation, you need to stop the preview, rotate and then start it again
if(mHolder.getSurface() == null)//check if the surface is ready to receive camera data
return;
try{
mCamera.stopPreview();
} catch (Exception e){
//this will happen when you are trying the camera if it's not running
}
//now, recreate the camera preview
try{
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (IOException e) {
Log.d("ERROR", "Camera error on surfaceChanged " + e.getMessage());
}
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
//our app has only one screen, so we'll destroy the camera in the surface
//if you are unsing with more screens, please move this code your activity
mCamera.stopPreview();
mCamera.release();
}
}
And this is my activity, which takes a picture and save it
public class MainActivity extends Activity implements OnClickListener {
String TAG = "Main activity";
private Camera mCamera = null;
private CameraView mCameraView = 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(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());
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// app en plein ecran
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
// CREATION DU DYNAMIQUE
final Button menu = (Button) findViewById(R.id.buttonMenu);
menu.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Perform action on click
Intent mainToMenu;
mainToMenu = new Intent(MainActivity.this, MenuActivity.class);
startActivity(mainToMenu);
}
});
try {
mCamera = Camera.open();//you can use open(int) to use different cameras
} catch (Exception e) {
Log.d("ERROR", "Failed to get camera: " + e.getMessage());
}
if(mCamera != null) {
mCameraView = new CameraView(this, mCamera);//create a SurfaceView to show camera data
FrameLayout camera_view = (FrameLayout)findViewById(R.id.camera_view);
camera_view.addView(mCameraView);//add the SurfaceView to the layout
}
// quand j appuis sur un btn volume
final Button b = (Button) findViewById(R.id.button);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Perform action on click
mCamera.takePicture(null, null, mPicture);
}
});
}
public static final int MEDIA_TYPE_IMAGE = 1;
/** Create a File for saving an image or video */
private static File getOutputMediaFile(int type){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "FotoFoto");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
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;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_"+ timeStamp + ".jpg");
} else {
return null;
}
return mediaFile;
}
#Override
public void onClick(View v) {
}
}
im beginner in android.
i have 2 class in 2 .java file. first:Mainacivity and second:ImageDownloader.
imagedownloader downloads bitmap with it's function getBitmapFromURL(String url), i give string to this function and it works well, but i wanna download more than 1 bitmap one after another.
my main activity:
public class MainActivity extends Activity implements View.OnClickListener
{
private Button download, downloadBG, save;
private ImageView img;
private ProgressBar pb;
private EditText etUrl;
private TextView percent;
private ImageDownloader mDownloader;
private static Bitmap bmp;
private FileOutputStream fos;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
/*--- initialize layout compinents ---*/
private void initViews() {
download = (Button) findViewById(R.id.btnDownload);
downloadBG = (Button) findViewById(R.id.btnDownloadBackground);
save = (Button) findViewById(R.id.btnSave);
/*--- we are using 'this' because our class implements the OnClickListener ---*/
download.setOnClickListener(this);
downloadBG.setOnClickListener(this);
save.setOnClickListener(this);
save.setEnabled(false);
img = (ImageView) findViewById(R.id.image);
img.setScaleType(ScaleType.CENTER_CROP);
pb = (ProgressBar) findViewById(R.id.pbDownload);
pb.setVisibility(View.INVISIBLE);
etUrl = (EditText) findViewById(R.id.etUrl);
percent = (TextView) findViewById(R.id.tvPercent);
percent.setVisibility(View.INVISIBLE);
}
#Override
public void onClick(View v) {
/*--- determine which button was clicked ---*/
switch (v.getId())
{
case R.id.btnDownload:
{
/*--- we use trim() to remove whitespaces which could be entered ---*/
bmp = ImageDownloader.getBitmapFromURL(URLbuilder(0, 0, 0));
img.setImageBitmap(bmp);
save.setEnabled(true);
break;
}
case R.id.btnDownloadBackground:
for(int a = 0 ; a < 4 ; a++)
{
/*--- check whether there is some Text entered ---*/
/*--- instantiate our downloader passing it required components ---*/
mDownloader = new ImageDownloader(URLbuilder(a, a, a), a,pb, save, img, percent, MainActivity.this, bmp, new ImageLoaderListener() {
#Override
public void onImageDownloaded(Bitmap bmp) {
MainActivity.bmp = bmp;
/*--- here we assign the value of bmp field in our Loader class
* to the bmp field of the current class ---*/
}
});
/*--- we need to call execute() since nothing will happen otherwise ---*/
mDownloader.execute();
}
break;
}
}
public String URLbuilder(int x , int y , int z)
{
String myurl = "http://khm0.google.com/kh/v=132&hl=EN&x={0}&y={1}&z={2}&s=";
String.format(myurl, x,y,z);
return String.format(myurl, x,y,z);
}
}
if i click on DownloadBackground button it should download 4 bitmap from it's url.
i know that each download take some time but i cannot stop this function untill first bitmap download.
my imagedownloader:
public class ImageDownloader extends AsyncTask<Void, Integer, Void>
{
private ProgressBar pb;
private String url;
private Button save;
private Context c;
private int progress;
private ImageView img;
private Bitmap bmp;
private TextView percent;
private ImageLoaderListener listener;
FileOutputStream fos;
int Counter = 0;
/*--- constructor ---*/
public ImageDownloader(String url,int counter, ProgressBar pb, Button save,
ImageView img, TextView percent, Context c, Bitmap bmp, ImageLoaderListener listener) {
/*--- we need to pass some objects we are going to work with ---*/
this.url = url;
this.pb = pb;
this.save = save;
this.c = c;
this.img = img;
this.percent = percent;
this.bmp = bmp;
this.listener = listener;
//this.Counter = Integer.toString(counter);
}
/*--- we need this interface for keeping the reference to our Bitmap from the MainActivity.
* Otherwise, bmp would be null in our MainActivity*/
public interface ImageLoaderListener {
void onImageDownloaded(Bitmap bmp);
}
#Override
protected void onPreExecute() {
progress = 0;
pb.setVisibility(View.VISIBLE);
percent.setVisibility(View.VISIBLE);
Toast.makeText(c, "starting download", Toast.LENGTH_SHORT).show();
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... arg0) {
bmp = getBitmapFromURL(url);
while (progress < 100) {
progress += 1;
publishProgress(progress);
/*--- an image download usually happens very fast so you would not notice
* how the ProgressBar jumps from 0 to 100 percent. You can use the method below
* to visually "slow down" the download and see the progress bein updated ---*/
//SystemClock.sleep(200);
}
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
/*--- show download progress on main UI thread---*/
pb.setProgress(values[0]);
percent.setText(values[0] + "%");
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(Void result) {
if (listener != null) {
listener.onImageDownloaded(bmp);
}
img.setImageBitmap(bmp);
saveImageToSD();
save.setEnabled(true);
Toast.makeText(c, "download complete", Toast.LENGTH_SHORT).show();
super.onPostExecute(result);
}
public static Bitmap getBitmapFromURL(String link)
{
/*--- this method downloads an Image from the given URL,
* then decodes and returns a Bitmap object
---*/
try {
URL url = new URL(link);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
} catch (IOException e) {
e.printStackTrace();
Log.e("getBmpFromUrl error: ", e.getMessage().toString());
return null;
}
}
private void saveImageToSD()
{
/*--- this method will save your downloaded image to SD card ---*/
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
/*--- you can select your preferred CompressFormat and quality.
* I'm going to use JPEG and 100% quality ---*/
bmp.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
/*--- create a new file on SD card ---*/
File file = new File(Environment.getExternalStorageDirectory()
+ File.separator + "myDownloadedImage" + Integer.toString(Counter) + ".jpg");
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
/*--- create a new FileOutputStream and write bytes to file ---*/
try {
fos = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
fos.write(bytes.toByteArray());
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
Counter++;
}
i need to stop for loop in onclick method in main activity until each image download. i did every things that i knew but every time it crashed.
later i have to put image downloader in a thread but i dont know how to stop thread for a while.
pls help me. ty
You can use Handler
new Handler().postDelayed(new Runnable(){
public void run() {
//some job to do delayed 3s
}}, 3000);
Hope it helps!
I've written a camera application, but when I want to show the camera's live preview(before taking the picture), the preview is rotated 90 degrees! here is my camera activity's code :
public class CameraActivity extends Activity{
public static final int MEDIA_TYPE_IMAGE = 1 ;
private Camera mCamera;
private CameraPreview mPreview;
Uri photoPath ;
protected void onStop()
{
super.onStop();
mCamera.release();
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
// Create an instance of Camera
mCamera = getCameraInstance();
// Create our Preview view and set it as the content of our activity.
mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
ViewGroup.LayoutParams previewParam = preview.getLayoutParams() ;
Parameters cameraParam = mCamera.getParameters() ;
double ratio = (double)cameraParam.getPictureSize().height / (double)cameraParam.getPictureSize().width ;
// previewParam.height= cameraParam.getPictureSize().height / 5 ;
// previewParam.width = cameraParam.getPictureSize().width / 5 ;
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
try
{
display.getSize(size);
}
catch(java.lang.NoSuchMethodError ignore)
{
size.x = display.getWidth();
size.y = display.getHeight() ;
}
int width = size.x;
int height = size.y;
previewParam.width = width;
previewParam.height = (int)(previewParam.width * ratio) ;
// preview.setLayoutParams(previewParam) ;
preview.addView(mPreview);
}
//Camera Classes here
private final static String TAG = "Navid";
public static Camera getCameraInstance()
{
Camera c = null ;
try
{
c = Camera.open() ;
}
catch(Exception e)
{
}
return c ;
}
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback
{
private SurfaceHolder mHolder ;
private Camera mCamera;
public CameraPreview(Context context , Camera camera)
{
super(context) ;
mCamera = camera ;
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder)
{
try
{
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
}
catch(IOException e)
{
Log.d(TAG,"Camera Preview Failed!: "+e.getMessage());
}
}
public void surfaceChanged(SurfaceHolder holder , int m , int n , int w)
{
}
public void surfaceDestroyed(SurfaceHolder holder)
{
}
}
private static File getOutputMediaFile(int type){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
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;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
}else {
return null;
}
return mediaFile;
}
//save the picture here
private PictureCallback mPicture = new PictureCallback() {
// public final static int MEDIA_TYPE_IMAGE = 1 ;
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
photoPath = Uri.fromFile(pictureFile);
if (pictureFile == null){
Log.d("Errore Doorbin", "Error creating media file, check storage permissions: ");
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
// these lines are for the gallery to scan the SDCard manually
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://"+ mediaStorageDir)));
// photoPath = Uri.fromFile(mediaStorageDir) ;
/* MediaScannerConnection.scanFile(CameraActivity.this,
new String[] { fos.toString() }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
// code to execute when scanning is complete
}
});*/
// fos.close();
} catch (FileNotFoundException e) {
Log.d("Errore Doorbin", "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d("Errore Doorbin", "Error accessing file: " + e.getMessage());
}
catch (Exception e)
{
Log.d("Errore Doorbin", "errore Kolli dade!" + e.getMessage()) ;
}
}
};
public void capture(View v)
{
//mCamera.takePicture(null, null, mPicture);
//mCamera.release();
//mCamera = getCameraInstance() ;
//mCamera.startPreview();
TakePictureTask takePicture = new TakePictureTask() ;
takePicture.execute() ;
}
public void accept(View v)
{
Intent data = new Intent() ;
data.setData(photoPath) ;
setResult(RESULT_OK, data);
finish() ;
}
public void retake(View v)
{
Button button = (Button)findViewById(R.id.button_accept);
button.setVisibility(View.GONE);
button = (Button)findViewById(R.id.button_capture) ;
button.setVisibility(View.VISIBLE) ;
button = (Button)findViewById(R.id.button_retake);
button.setVisibility(View.GONE) ;
mCamera.startPreview();
}
/**
* A pretty basic example of an AsyncTask that takes the photo and
* then sleeps for a defined period of time before finishing. Upon
* finishing, it will restart the preview - Camera.startPreview().
*/
private class TakePictureTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPostExecute(Void result) {
// This returns the preview back to the live camera feed
Button button = (Button)findViewById(R.id.button_accept) ;
button.setVisibility(View.VISIBLE) ;
button = (Button)findViewById(R.id.button_retake) ;
button.setVisibility(View.VISIBLE);
button = (Button)findViewById(R.id.button_capture);
button.setVisibility(View.GONE);
//mCamera.startPreview();
}
#Override
protected Void doInBackground(Void... params) {
mCamera.takePicture(null, null, mPicture);
// Sleep for however long, you could store this in a variable and
// have it updated by a menu item which the user selects.
try {
Thread.sleep(3000); // 3 second preview
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
}
and in my application's manifest I've changed this activities orientation to portrait!
What is the problem ? why does it look like this ?
This happens to be a bug in earlier versions of Android.
A workaround is to rotate the camera by default.
if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
camera.setDisplayOrientation(90);
lp.height = previewSurfaceHeight;
lp.width = (int) (previewSurfaceHeight / aspect);
} else {
camera.setDisplayOrientation(0);
lp.width = previewSurfaceWidth;
lp.height = (int) (previewSurfaceWidth / aspect);
}
I am able to place a overlay over a live camera feed, but I also need to save the image captured by camera with that overlay.
Here is the code of my MainActivity.class file :
public class MainActivity extends Activity {
private Button takePhoto, pickPhoto;
private FrameLayout preview;
private CameraSurfaceView cameraSurfaceView;
private static final int SELECT_PICTURE_ACTIVITY_RESULT_CODE = 1;
private static final int CAMERA_PIC_REQUEST = 2;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
takePhoto = (Button) findViewById(R.id.btn_takephoto);
pickPhoto = (Button) findViewById(R.id.btn_pickPhoto);
preview = (FrameLayout) findViewById(R.id.frameLayout1);
takePhoto.setOnClickListener(clickListener);
pickPhoto.setOnClickListener(clickListener);
cameraSurfaceView = new CameraSurfaceView(MainActivity.this);
preview.addView(cameraSurfaceView);
}
View.OnClickListener clickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
if (v.equals(takePhoto)) {
Camera camera = cameraSurfaceView.getCamera();
camera.takePicture(null, null, new HandlePictureStorage());
} else if (v.equals(pickPhoto)) {
Intent photoPickerIntent = new Intent();
photoPickerIntent.setType("image/*"); // to pick only images
photoPickerIntent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(photoPickerIntent,
SELECT_PICTURE_ACTIVITY_RESULT_CODE);
}
}
};
private class HandlePictureStorage implements PictureCallback {
#Override
public void onPictureTaken(byte[] picture, Camera camera) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyymmddhhmmss");
String date = dateFormat.format(new Date());
String photoFile = "CameraTest" + date + ".jpg";
String filename = Environment.getExternalStorageDirectory()
+ File.separator + photoFile;
File pictureFile = new File(filename);
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(picture);
fos.close();
Toast.makeText(getApplicationContext(),
"New Image saved:" + photoFile, Toast.LENGTH_LONG)
.show();
} catch (Exception error) {
Log.d("Error",
"File" + filename + "not saved: " + error.getMessage());
Toast.makeText(getApplicationContext(),
"Image could not be saved.", Toast.LENGTH_LONG).show();
}
Intent newInt = new Intent(MainActivity.this, AddImageOverlay.class);
newInt.putExtra(Constant.BitmatpByteArray, filename);
startActivity(newInt);
}
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
switch (requestCode) {
case SELECT_PICTURE_ACTIVITY_RESULT_CODE:
Uri selectedImageUri = data.getData();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(
this.getContentResolver(), selectedImageUri);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(), "Photo Picked",
Toast.LENGTH_SHORT).show();
// deal with it
break;
default:
// deal with it
break;
}
}
}
}
And the code of CameraSurfaceView.java :
public class CameraSurfaceView extends SurfaceView implements
SurfaceHolder.Callback {
private SurfaceHolder holder;
private Camera camera;
public CameraSurfaceView(Context context) {
super(context);
// Initiate the Surface Holder properly
this.holder = this.getHolder();
this.holder.addCallback(this);
this.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
public void surfaceChanged(SurfaceHolder h, int format, int width,
int height) {
// Now that the size is known, set up the camera parameters and begin
// the preview.
Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewSize(width, height);
camera.setParameters(parameters);
camera.startPreview();
h.getSurface().setLayer(R.drawable.ic_launcher);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
// Open the Camera in preview mode
this.camera = Camera.open();
this.camera.setPreviewDisplay(this.holder);
} catch (IOException ioe) {
ioe.printStackTrace(System.out);
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when replaced with a new screen
// Always make sure to release the Camera instance
camera.stopPreview();
camera.release();
camera = null;
}
public Camera getCamera() {
return this.camera;
}
}