CameraCaptureActivity от Grafika - предварительный просмотр камеры искажается при изменении размера предварительного просмотра

Я сослался на CameraCaptureActivity от Grafika для записи видео с одновременным отображением предварительного просмотра камеры.

Изменения, которые я внес в код (это актуально) -

Пользователь нажимает кнопку для запуска PreferencesActivity, выбирает предпочтительное разрешение камеры (в котором хранится width а также height значения) и нажимает кнопку "Назад", чтобы вернуться к CameraCaptureActivity,

в openCamera метод- вместо жесткого кодирования width а также height Я выбираю значения из SharedPreferences

AspectFrameLayout's атрибут установлен таким образом android:background="@android:color/holo_blue_bright", Таким образом, предварительный просмотр соответствует размеру AspectFrameLayout

Эта проблема возникает в основном при изменении размера с большего разрешения на меньшее.

На экранах меньшего размера (HTC One M7 / Xperia SP) Искаженный предварительный просмотр камеры в HTC

В больших экранах (Samsung Galaxy Tab S / Nexus 9) - Искаженный предварительный просмотр камеры в Samsung Tab S

Я заметил, что это происходит потому, что onSurfaceChanged вызывается дважды. В первый раз это с неправильными значениями для width а также height и во второй раз это с правильными значениями.

Тем не менее, макет выглядит хорошо, если я оставляю активность и возвращаюсь к ней, не внося никаких изменений. (Как собирается PreferencesActivity и нажав "Назад" без изменения разрешения.)

Я установил следующее в AndroidManifest.xml -

<activity android:name=".activity.camera.CameraCaptureActivity"
 android:launchMode="singleInstance"
 android:screenOrientation="landscape"
 android:theme="@android:style/Theme.Holo.Light.NoActionBar">
</activity>

РЕДАКТИРОВАТЬ: эта проблема возникает только с предварительного просмотра. Записанное видео имеет правильный размер.

РЕДАКТИРОВАТЬ 2: Это мой layout.xml

    <RelativeLayout xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/cameracapturescreen_rootparent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black"
tools:context="com.myapp.CameraCaptureActivity">

<com.myapp.activity.camera.PreviewFrameLayout
    android:id="@+id/surfaceview_framelayout"
    android:layout_width="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_centerVertical="true"
    android:background="@android:color/holo_blue_bright"
    android:layout_height="wrap_content">

    <android.opengl.GLSurfaceView
        android:id="@+id/cameraPreview_surfaceView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="left"/>

</com.myapp.activity.camera.PreviewFrameLayout>

Я уверен, что передаю правильные значения, чтобы установить ширину и высоту представления, потому что предварительный просмотр настроен правильно, если я покидаю упражнение и возвращаюсь к нему без внесения каких-либо изменений. (Например, перейти к другому занятию и нажать "Назад", чтобы вернуться к CameraCaptureActivity.)

2 ответа

Решение

Мне непонятно, что вы пытаетесь сказать, если проблема связана с предварительным просмотром... тогда вы можете использовать следующий код в методе открытой камеры

добавить код этой вещи в ваш метод openCamera(), я только что проверил это... надеюсь, это поможет

    if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
        mCamera.setDisplayOrientation(90);
    } else {
        mCamera.setDisplayOrientation(180);
    }

Добавьте этот код в ваш метод handleSetSurfaceTexture()

    if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
        mCamera.setDisplayOrientation(90);
     } else {
        mCamera.setDisplayOrientation(180);
    }
          Camera.Parameters parms = mCamera.getParameters();

          CameraUtils.choosePreviewSize(parms, mCameraPreviewWidth, mCameraPreviewHeight);

          // Give the camera a hint that we're recording video.  This   can have a big
          // impact on frame rate.
          parms.setRecordingHint(true);
          mCamera.setParameters(parms);

и эта часть кода в вашем onPause()

InputMethodManager imm = (InputMethodManager)getSystemService(
Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(((EditText)findViewById(R.id.username)).getWindowToken(), 0);

if(imm.isAcceptingText()) {
Intent intent = new Intent(this, CameraCaptureActivity.class);
startActivity(intent);
}

Используйте это, чтобы открыть камеру

Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);    
i.putExtra(MediaStore.EXTRA_OUTPUT, MyFileContentProvider.CONTENT_URI); 
startActivityForResult(i, CAMERA_RESULT);

Вот класс MyFileContentProvider

public class MyFileContentProvider extends ContentProvider {

 public static final Uri CONTENT_URI = Uri.parse("content://com.algorithmapps.dmsimagesave/");

 private static final HashMap<String, String> MIME_TYPES = new         HashMap<String, String>();

 static {

  MIME_TYPES.put(".jpg", "image/jpeg");

  MIME_TYPES.put(".jpeg", "image/jpeg");

 }

 @Override

 public boolean onCreate() {

  try {

   File mFile = new File(getContext().getFilesDir(), "newImage.jpg");

   if(!mFile.exists()) {

mFile.createNewFile();

   }

   getContext().getContentResolver().notifyChange(CONTENT_URI, null);

   return (true);

  } catch (Exception e) {

   e.printStackTrace();

   return false;

  }

 }

 @Override

 public String getType(Uri uri) {

  String path = uri.toString();

  for (String extension : MIME_TYPES.keySet()) {

   if (path.endsWith(extension)) {

    return (MIME_TYPES.get(extension));

   }

  }

  return (null);

 }

 @Override

 public ParcelFileDescriptor openFile(Uri uri, String mode)

 throws FileNotFoundException {

  File f = new File(getContext().getFilesDir(), "newImage.jpg");

  if (f.exists()) {

   return (ParcelFileDescriptor.open(f,

     ParcelFileDescriptor.MODE_READ_WRITE));

  }

  throw new FileNotFoundException(uri.getPath());

 }

 @Override

 public Cursor query(Uri url, String[] projection, String selection,

   String[] selectionArgs, String sort) {

  throw new RuntimeException("Operation not supported");

 }

 @Override

 public Uri insert(Uri uri, ContentValues initialValues) {

  throw new RuntimeException("Operation not supported");

 }

 @Override

 public int update(Uri uri, ContentValues values, String where,

   String[] whereArgs) {

  throw new RuntimeException("Operation not supported");

 }

 @Override

 public int delete(Uri uri, String where, String[] whereArgs) {

  throw new RuntimeException("Operation not supported");

 }

} 

В onActivityResultMethod получить изображение, как это

 if (resultCode == RESULT_OK && requestCode == CAMERA_RESULT) {

       File out = new File(getFilesDir(), "newImage.jpg");

         if(!out.exists()) {

                Toast.makeText(getBaseContext(),

                  "Error while capturing image", Toast.LENGTH_LONG)

                  .show();


       }             
          originalBitmap = BitmapFactory.decodeFile(out.getAbsolutePath());   
    }

чем изменить размер растрового изображения с помощью этого кода, здесь я изменяю размер для ширины 200 * 200

BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;

Bitmap resizedBitmap = Bitmap.createScaledBitmap(originalBitmap, 200, 200, false);

Этот метод не позволит вашему искаженному изображению изменяться. Надеюсь, поможет.

Другие вопросы по тегам