Android相机照片预览正在逆转

博观而约取,厚积而薄发。这篇文章主要讲述Android相机照片预览正在逆转相关的知识,希望能为你提供帮助。
我正在开发与相关的应用程序。我已成功完成拍摄照片和照片预览。但是出现了一个问题。当我拍照时,照片拍摄成功但预览正在逆转。我已经尝试过很多来自堆栈溢出的解决方案,但到目前为止运气并不适合我。
我的相机预览课程是:

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { private SurfaceHolder mHolder; private Camera mCamera; private Context mContext; public CameraPreview(Context context, Camera camera) { super(context); mContext = context; mCamera = camera; mHolder = getHolder(); mHolder.addCallback(this); // deprecated setting, but required on android versions prior to 3.0 mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); }public void surfaceCreated(SurfaceHolder holder) { try { // create the surface and start camera preview if (mCamera == null) { mCamera.setPreviewDisplay(holder); mCamera.startPreview(); } } catch (IOException e) { Log.d(VIEW_LOG_TAG, "Error setting camera preview: " + e.getMessage()); } }public void refreshCamera(Camera camera) { if (mHolder.getSurface() == null) { // preview surface does not exist return; } // stop preview before making changes try { mCamera.stopPreview(); } catch (Exception e) { // ignore: tried to stop a non-existent preview } // set preview size and make any resize, rotate or // reformatting changes here // start preview with new settings setCamera(camera); // TODO: don't hardcode cameraId '0' here... figure this out later. setCameraDisplayOrientation(mContext, Camera.CameraInfo.CAMERA_FACING_BACK, mCamera); try { mCamera.setPreviewDisplay(mHolder); mCamera.startPreview(); } catch (Exception e) { Log.d(VIEW_LOG_TAG, "Error starting camera preview: " + e.getMessage()); } }public static void setCameraDisplayOrientation(Context context, int cameraId, Camera camera) { WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); int rotation = wm.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; }Camera.CameraInfo info = new Camera.CameraInfo(); Camera.getCameraInfo(cameraId, info); int result; if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { result = (info.orientation + degrees) % 360; // Compensate for the mirror image. result = (360 - result) % 360; } else { // Back-facing camera. result = (info.orientation - degrees + 360) % 360; } camera.setDisplayOrientation(result); }public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { // If your preview can change or rotate, take care of those events here. // Make sure to stop the preview before resizing or reformatting it. refreshCamera(mCamera); }public void setCamera(Camera camera) { //method to set a camera instance mCamera = camera; }@Override public void surfaceDestroyed(SurfaceHolder holder) { // TODO Auto-generated method stub // mCamera.release(); } }

我的PhotoCaputeActivity课程如下:
public class PhotoCaptureActivity extends AppCompatActivity {private static final String TAG = "PhotoCaptureActivity"; //Arraylist for image timer animation int[] imageArray = {R.drawable.ic_five_128, R.drawable.ic_four_128, R.drawable.ic_three_128, R.drawable.ic_two_128, R.drawable.ic_one_128, R.drawable.ic_smiley_128 }; int i = 0; private final static int DELAY = 1000; private final Handler handler = new Handler(); Timer timer = new Timer(); Thread timerThread; // Create variable to handle progress and set it to 0. private int progress = 0; Bitmap bitmap,photoCaptureBitmap; private Camera mCamera; private CameraPreview mPreview; private PictureCallback mPicture; private ImageButton capture, switchCamera; private Context myContext; private LinearLayout cameraPreview; private boolean cameraFront = false; private ImageView capturedImageHolder; private ProgressBar progressBar_take_photo; ImageButton next_button_take_photo; ImageButton back_button_take_photo; TextView photo_title_text; ImageView image_animation; private MyPreferences myPreferences; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getSupportActionBar().setDisplayShowTitleEnabled(false); setContentView(R.layout.photo_capture_activity); //setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); Logger.addLogAdapter(new AndroidLogAdapter()); myContext = this; initialize(); myPreferences = MyPreferences.getPreferences(this); nextButton(); backButton(); progressBar(); nameTextShow(); }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, "", Toast.LENGTH_LONG).show(); //switchCamera.setVisibility(View.GONE); } mCamera = Camera.open(findFrontFacingCamera()); mPicture = getPictureCallback(); mPreview.refreshCamera(mCamera); }else{ //Visibility cameraPreview.setVisibility(View.GONE); capturedImageHolder.setVisibility(View.VISIBLE); String photoCapturePreview = myPreferences.getVisitorPhoto(); if(!photoCapturePreview.equals("")) { photoCaptureBitmap = decodeToBase64(photoCapturePreview); } capturedImageHolder.setImageBitmap(photoCaptureBitmap); } }public static Bitmap decodeToBase64(String input) { byte[] decodedByte = Base64.decode(input, 0); return BitmapFactory.decodeByteArray(decodedByte, 0, decodedByte.length); }// Code for initialization public void initialize() { cameraPreview = (LinearLayout) findViewById(R.id.cameraFrame); mPreview = new CameraPreview(myContext, mCamera); cameraPreview.addView(mPreview); capture = (ImageButton) findViewById(R.id.button_capture); capture.setOnClickListener(captrureListener); //switchCamera = (Button) findViewById(R.id.button_ChangeCamera); //switchCamera.setOnClickListener(switchCameraListener); image_animation = (ImageView) findViewById(R.id.timer_text); capturedImageHolder = (ImageView) findViewById(R.id.captured_image); next_button_take_photo = (ImageButton) findViewById(R.id.next_button_take_photo); back_button_take_photo = (ImageButton) findViewById(R.id.back_button_take_photo); progressBar_take_photo = (ProgressBar) findViewById(R.id.progressBar_take_photo); photo_title_text = (TextView) findViewById(R.id.photo_title_text); }//Next Button operation based on mobile number input private void nextButton() { next_button_take_photo.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { hideKeyboard(); if (bitmap != null) { Intent newIntent = new Intent(getApplicationContext(), ConfirmationActivity.class); startActivity(newIntent); } } }); }//Back button operation private void backButton() { back_button_take_photo.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) {Intent newIntent = new Intent(getApplicationContext(), AddressInputActivity.class); startActivity(newIntent); } }); }//Progress bar operation private void progressBar() {//simpleProgressBar.setMax(100); // 100 maximum value for the progress value //simpleProgressBar.setProgress(50); // 50 default progress value for the progress bar// Get the Drawable custom_progressbar //Drawable draw=res.getDrawable(R.drawable.custom_progressbar); // set the drawable as progress drawable //progressBar.setProgressDrawable(draw); }//Normal text show private void nameTextShow() { String vsitorName = myPreferences.getVisitorName(); photo_title_text.setText(vsitorName + ", please smile for the Camera"); }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 versareleaseCamera(); 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 previewmCamera = Camera.open(cameraId); mPicture = getPictureCallback(); mPreview.refreshCamera(mCamera); } } else { int cameraId = findFrontFacingCamera(); if (cameraId > = 0) { //open the backFacingCamera //set a picture callback //refresh the previewmCamera = 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_ANY)) { return true; } else { return false; } }private PictureCallback getPictureCallback() { PictureCallback picture = new PictureCallback() {@Override public void onPictureTaken(byte[] data, Camera camera) {if (data != null) { //make a new picture file File pictureFile = getOutputMediaFile(); bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); String imageEncoded = Base64.encodeToString(data, Base64.DEFAULT); myPreferences.setVisitorPhoto(imageEncoded); if (bitmap == 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(); //Method for image view captureImageView(); } catch (FileNotFoundException e) { } catch (IOException e) { }//refresh camera to continue preview mPreview.refreshCamera(mCamera); } } }; return picture; }**private void captureImageView(){ //Visibitlity of camera photo cameraPreview.setVisibility(View.GONE); capturedImageHolder.setVisibility(View.VISIBLE); int screenWidth = getResources().getDisplayMetrics().widthPixels; int screenHeight = getResources().getDisplayMetrics().heightPixels; Camera.CameraInfo info = new Camera.CameraInfo(); Matrix mtx = new Matrix(); if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { // Notice that width and height are reversed Bitmap scaled = Bitmap.createScaledBitmap(bitmap, screenHeight, screenWidth, true); int w = scaled.getWidth(); int h = scaled.getHeight(); // Perform matrix rotations/mirrors depending on camera that took the photo if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { float[] mirrorY = { -1, 0, 0, 0, 1, 0, 0, 0, 1}; Matrix matrixMirrorY = new Matrix(); matrixMirrorY.setValues(mirrorY); mtx.postConcat(matrixMirrorY); }// Setting post rotate to 90 mtx.postRotate(270); // Rotating Bitmap bitmap = Bitmap.createBitmap(scaled, 0, 0, w, h, mtx, true); //capturedImageHolder.setImageBitmap(bitmap); capturedImageHolder.setImageBitmap(scaleDownBitmapImage(bitmap, 350, 450)); }else{// LANDSCAPE MODE //No need to reverse width and height Bitmap scaled = Bitmap.createScaledBitmap(bitmap, screenWidth,screenHeight , true); bitmap=scaled; //capturedImageHolder.setImageBitmap(bitmap); capturedImageHolder.setImageBitmap(scaleDownBitmapImage(bitmap, 650, 300)); } }**private Bitmap scaleDownBitmapImage(Bitmap bitmap, int newWidth, int newHeight) { Bitmap resizedBitmap = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true); return resizedBitmap; }OnClickListener captrureListener = new OnClickListener() { @Override public void onClick(View v) {//Visibitlity of camera photo cameraPreview.setVisibility(View.VISIBLE); capturedImageHolder.setVisibility(View.GONE); new Loading().execute(); //timer.schedule(task, DELAY, DELAY); timerThread = new Thread() { public void run() { for (i = 0; i < 6; i++) { runOnUiThread(new Runnable() { public void run() { image_animation.setImageResource(imageArray[i]); } }); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } if(i==6){ timerThread.interrupt(); } } } }; timerThread.start(); } }; private final TimerTask task = new TimerTask() { private int counter = 0; public void run() { handler.post(new Runnable() { public void run() { image_animation.setImageResource(imageArray[i]); i++; if (i > imageArray.length - 1) { i = 0; } } }); if (++counter == 6) { timer.cancel(); timer.purge(); } } }; public class Loading extends AsyncTask< Void, Void, Void> {@Override protected Void doInBackground(Void... voids) { return null; }@Override protected void onPostExecute(Void aVoid) { super.onPostExecute(aVoid); // 6000ms=6s at intervals of 1000ms=1s so that means it lasts 5 seconds new CountDownTimer(5000, 1000) {@Override public void onTick(long millisUntilFinished) { // every time 1 second passes //tv.setText("" + millisUntilFinished/1000); /* image_animation.setImageResource(imageArray[i]); i++; if (i > imageArray.length - 1) { i = 0; }*/ }@Override public void onFinish() { // count finished //tv.setText("Picture Taken"); mCamera.takePicture(null, null, null, mPicture); }}.start(); } }//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; } }private void hideKeyboard() { View view = getCurrentFocus(); if (view != null) { ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)). hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); } }@Override public void onBackPressed() { // code here to show dialog super.onBackPressed(); // optional depending on your needs }@Override protected void onDestroy() { if (mCamera != null) { mCamera.release(); } super.onDestroy(); }@Override public void onStop() { if (mCamera != null) { mCamera.release(); } super.onStop(); } }

我现在得到的结果是什么,我想要的是下面的结果。请在拍照期间看到手在右侧,但是当显示照片预览时,它显示在左侧。
那么,如何解决这个问题呢?
Android相机照片预览正在逆转

文章图片

答案最后我通过在imageview中添加以下属性来获得解决方案,并且像魅力一样工作:)
机器人:将scaleX = “ -1”
另一答案不幸的是我们无法禁用镜像预览,但我们可以使用TextureView并应用SetTransform来反转相机预览,这只适用于API> = 14。请尝试使用PhotoCaputeActivity中的以下代码
mCamera.setDisplayOrientation(90); Matrix matrix = new Matrix(); matrix.setScale(-1, 1); matrix.postTranslate(width, 0); mTextureView.setTransform(matrix);

有关更多信息,请查看this link.
还要记住
【Android相机照片预览正在逆转】这与前置摄像头一起使用,当使用后置摄像头进行尝试时,请使用mTextureView.setTransform(null);

    推荐阅读