There is activity with SurfaceView and ImageButton . SurfaceView displays the frames received from the camera. When I click on the button, the Camera.takePicture(...) method is onPictureTaken(byte[] data, Camera camera) , and in the onPictureTaken(byte[] data, Camera camera) method onPictureTaken(byte[] data, Camera camera) I create a new activity and transfer the image byte array there.

MainActivity code:

 import android.app.Activity; import android.content.Intent; import android.content.pm.ActivityInfo; import android.hardware.Camera; import android.os.Bundle; import android.util.DisplayMetrics; import android.util.Log; import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; import android.widget.ImageButton; import com.example.user.task8.R; import java.io.IOException; public class MainActivity extends Activity implements SurfaceHolder.Callback, Camera.PreviewCallback, Camera.PictureCallback { private static final String TAG = "MainActivity"; private static final String PHOTO_DIR = "Task8"; private Camera camera; private SurfaceHolder surfaceHolder; private SurfaceView preview; private ImageButton shotButton; public void takePicture(View view) { camera.takePicture(null, null, this); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Window settings setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.a_main); preview = (SurfaceView) findViewById(R.id.surface); surfaceHolder = preview.getHolder(); surfaceHolder.addCallback(this); shotButton = (ImageButton) findViewById(R.id.button_shot); } @Override protected void onResume() { super.onResume(); camera = Camera.open(); // It is way to fix freezing a surface on screen locking preview.setVisibility(View.VISIBLE); } @Override protected void onPause() { super.onPause(); // It is way to fix freezing a surface on screen locking preview.setVisibility(View.GONE); if (camera != null) { camera.setPreviewCallback(null); camera.stopPreview(); camera.release(); camera = null; } } @Override public void surfaceCreated(SurfaceHolder holder) { try { camera.setPreviewDisplay(holder); camera.setPreviewCallback(this); } catch (IOException e) { Log.e(TAG, e.toString()); } camera.setDisplayOrientation(90); Camera.Size previewSize = camera.getParameters().getPreviewSize(); float aspect = (float) previewSize.width / previewSize.height; int previewSurfaceWidth = preview.getWidth(); int previewSurfaceHeight = preview.getHeight(); ViewGroup.LayoutParams lp = preview.getLayoutParams(); lp.height = previewSurfaceHeight; lp.width = (int) (previewSurfaceHeight / aspect); preview.setLayoutParams(lp); camera.startPreview(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { } @Override public void onPreviewFrame(byte[] data, Camera camera) { } @Override public void onPictureTaken(byte[] data, Camera camera) { Log.d(TAG, "onPictureTaken"); Intent intent = new Intent(this, PictureActivity.class); intent.putExtra(PictureActivity.PICTURE_DATA, data); startActivity(intent); } } 

In the new activity I decode the array into bitmap, in turn I turn it over and output it into ImageView . But the quality of the image, to put it mildly, terrible.

PictureActivity Code:

 import android.app.Activity; import android.content.pm.ActivityInfo; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.os.Bundle; import android.view.Window; import android.view.WindowManager; import android.widget.ImageView; import com.example.user.task8.R; public class PictureActivity extends Activity { public static final String PICTURE_DATA = "PICTURE_DATA"; private static final String TAG = "PictureActivity"; private ImageView imageView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Window settings getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.a_picture); imageView = (ImageView) findViewById(R.id.picture_view); byte[] data = getIntent().getByteArrayExtra(PICTURE_DATA); Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); Matrix matrix = new Matrix(); matrix.postRotate(90); imageView.setImageBitmap(Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true)); } @Override protected void onResume() { super.onResume(); } } 

Question : how can I get the picture quality is the same as in the preview? And is it possible to get such an image using the existing structure of the application?

    1 answer 1

    Use params.setPictureSize() . See more in Camera.Parameters

    params.getSupportedPictureSizes() returns a list of supported sizes. You must select the desired size and specify it with setPictureSize()

     Camera.Parameters params = camera.getParameters(); List<Camera.Size> supportedSizes = params.getSupportedPictureSizes(); Camera.Size sizePicture = (one of the sizes from supportedSizes list); params.setPictureSize(sizePicture.width, sizePicture.height); 
    • Thanks, helped! - Dmitriy