我正在开发与相关相关的应用。我已成功完成拍摄照片和照片预览。但是出现了一个问题。当我拍照时,照片拍摄成功但预览正在逆转。我已经从堆栈溢出中尝试了很多解决方案,但到目前为止运气并没有对我有利。
我的相机预览课程是:
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 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_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();
}
}
我现在得到的结果是什么,以及我想要的结果如下。请在拍照期间看到手在右侧,但是当显示照片预览时,它显示在左侧。
那么,可以采取哪些措施来解决这个问题?
答案 0 :(得分:1)
最后,我通过在imageview中添加以下属性来获得解决方案,并且像魅力一样工作:)
机器人:将scaleX = “ - 1”
答案 1 :(得分:0)
很遗憾,我们无法禁用镜像预览,但我们可以使用TextureView并应用SetTransform来反转相机预览,这仅适用于API&gt; = 14。请尝试使用PhotoCaputeActivity中的以下代码
mCamera.setDisplayOrientation(90);
Matrix matrix = new Matrix();
matrix.setScale(-1, 1);
matrix.postTranslate(width, 0);
mTextureView.setTransform(matrix);
了解详情this link.
还要记住
这与前置摄像头一起使用,当使用后置摄像头尝试时 mTextureView.setTransform(null);
答案 2 :(得分:0)
在OpenCV JavaCameraView中,这非常简单
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
imageMat = inputFrame.rgba().t();
if (//horizontal reverse)
Core.flip(imageMat, imageMat, 1);
else //for vertical reverse
Core.flip(imageMat, imageMat, -1);