Как исправить размытый экран предварительного просмотра камеры [закрыто] ⇐ Android
Как исправить размытый экран предварительного просмотра камеры [закрыто]
Я пытаюсь создать экран предварительного просмотра с наложением круга поверх него. В соответствии с требованиями проекта экран предварительного просмотра должен быть достаточно большим, чтобы полностью вместить круг. В требованиях проекта также указано, что существуют максимальные размеры, которые никогда не могут быть превышены независимо от устройства из-за риска превышения ограничения пропускной способности шины камеры, что приводит к великолепным предварительным просмотрам, но к хранению данных захвата мусора.
Чтобы учесть это, я в основном сделал так, чтобы ширина экрана предварительного просмотра была установлена на максимальную ширину или на ширину экрана, если устройство недостаточно велико. Он получил те размеры, которые мне нужны для экрана предварительного просмотра, но он очень увеличен и размыт.
Я не знаю, как получить правильные размеры и сохранить хорошее качество камеры. Буду очень признателен за любую помощь в исправлении этой проблемы.
Соответствующие фрагменты кода:
AutoFitTextureView.java:
пакет edu.washington.cs.ubicomplab.camera2skeleton; импортировать android.content.Context; импортировать android.util.AttributeSet; импортировать android.view.TextureView; /** * {@link TextView}, который можно настроить под указанное соотношение сторон. */ публичный класс AutoFitTextureView расширяет TextView { частный int mRatioWidth = 0; частный int mRatioHeight = 0; public AutoFitTextureView (контекстный контекст) { это (контекст, ноль); } public AutoFitTextureView (контекст контекста, атрибуты AttributeSet) { это (контекст, атрибуты, 0); } public AutoFitTextureView (контекст контекста, атрибуты AttributeSet, int defStyle) { супер(контекст, атрибуты, defStyle); } /** * Устанавливает соотношение сторон для этого вида. Размер представления будет измеряться на основе соотношения * рассчитано по параметрам. Обратите внимание, что фактические размеры параметров не имеют значения, т.е. * есть, вызов setAspectRatio(2, 3) и setAspectRatio(4, 6) дает тот же результат. * * @param width Относительный горизонтальный размер * @param height Относительный размер по вертикали */ public void setAspectRatio (ширина int, высота int) { если (ширина < 0 || высота < 0) { throw new IllegalArgumentException("Размер не может быть отрицательным."); } mRatioWidth = ширина; mRatioHeight = высота; запросLayout(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int width = MeasureSpec.getSize(widthMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); if (0 == mRatioWidth || 0 == mRatioHeight) { setMeasuredDimension (ширина, высота); } еще { if (ширина < высота * mRatioWidth / mRatioHeight) { setMeasuredDimension (ширина, ширина * mRatioHeight / mRatioWidth); } еще { setMeasuredDimension (высота * mRatioWidth / mRatioHeight, высота); } } } } setUpCameraOutputs и выберите методы OptimalSize в Camera2Fragment.java:
/** * Учитывая {@code choice} из {@code Size}, поддерживаемых камерой, выберите наименьший из них, который * по крайней мере равен размеру соответствующего представления текстуры и не превышает размера * соответствующий максимальный размер и соотношение сторон которого соответствует указанному значению. Если такой размер * не существует, выберите самый большой, размер которого не превышает соответствующего максимального размера, * и соотношение сторон которого соответствует указанному значению. * * @param choice Список размеров, которые поддерживает камера для предполагаемого вывода. * сорт * @paramtextureViewWidth Ширина изображения текстуры относительно координаты датчика. * @paramtextureViewHeight Высота изображения текстуры относительно координаты датчика. * @param maxWidth Максимальная ширина, которую можно выбрать. * @param maxHeight Максимальная высота, которую можно выбрать. * @paramspectRatio Соотношение сторон * @return Оптимальный {@размер кода} или произвольный, если ни один из них не был достаточно большим. */ частный статический размер ChooseOptimalSize (Выбор размера [], inttextureViewWidth, inttextureViewHeight, int maxWidth, int maxHeight, SizespectRatio) { // Собираем поддерживаемые разрешения, по крайней мере такие же большие, как поверхность предварительного просмотра List bigEnough = новый ArrayList(); // Собираем поддерживаемые разрешения, которые меньше поверхности предварительного просмотра List notBigEnough = новый ArrayList(); int w = аспектRatio.getWidth(); int h = аспектRatio.getHeight(); для (вариант размера: выбор) { if (option.getWidth() = текстураViewHeight) { bigEnough.add (опция); } еще { notBigEnough.add (опция); } } } // Выбираем самый маленький из достаточно больших. Если нет никого достаточно большого, выберите // самый большой из недостаточно больших. если (bigEnough.size() > 0) { return Collections.min(bigEnough, new CompareSizesByArea()); } else if (notBigEnough.size() > 0) { return Collections.max(notBigEnough, new CompareSizesByArea()); } еще { Log.e(TAG, «Не удалось найти подходящий размер предварительного просмотра»); возврат выбора[0]; } } /** * Устанавливает переменные-члены, связанные с камерой. * * @param width Ширина доступного размера для предварительного просмотра камеры. * @param height Высота доступного размера для предварительного просмотра камеры. */ @SuppressWarnings («Подозрительная комбинация имен») Private void setUpCameraOutputs (ширина int, высота int) { Активность активности = getActivity(); Менеджер CameraManager = (CameraManager) Activity.getSystemService(Context.CAMERA_SERVICE); пытаться { for (String cameraId: Manager.getCameraIdList()) { КамераХарактеристики характеристики = менеджер.getCameraCharacteristics(cameraId); // В этом примере мы не используем фронтальную камеру. Целочисленное лицо = характеристики.get(CameraCharacteristics.LENS_FACING); if (лицом!= null && лицом == CameraCharacteristics.LENS_FACING_FRONT) { продолжать; } Карта StreamConfigurationMap = характеристики.get( CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); если (карта == ноль) { продолжать; } // Для захвата неподвижных изображений мы используем наибольший доступный размер. Наибольший размер = Collections.max( Arrays.asList(map.getOutputSizes(ImageFormat.YUV_420_888)), новый CompareSizesByArea()); mImageReader = ImageReader.newInstance(largest.getWidth(), крупнейших.getHeight(), ImageFormat.YUV_420_888, /*maxImages*/2); mImageReader.setOnImageAvailableListener( mOnImageAvailableListener, mBackgroundHandler); // Выясняем, нужно ли нам поменять размер, чтобы получить размер предварительного просмотра относительно датчика // координата. int displayRotation = Activity.getWindowManager().getDefaultDisplay().getRotation(); //без проверки константных условий mSensorOrientation = характеристики.get(CameraCharacteristics.SENSOR_ORIENTATION); логическое значение swappedDimensions = false; переключатель (displayRotation) { корпус Surface.ROTATION_0: чехол Surface.ROTATION_180: if (mSensorOrientation == 90 || mSensorOrientation == 270) { swappedDimensions = правда; } перерыв; чехол Surface.ROTATION_90: чехол Surface.ROTATION_270: if (mSensorOrientation == 0 || mSensorOrientation == 180) { swappedDimensions = правда; } перерыв; по умолчанию: Log.e(TAG, "Недопустимый поворот дисплея: " + displayRotation); } Point displaySize = новая точка(); Activity.getWindowManager().getDefaultDisplay().getSize(displaySize); Log.d(TAG, "Размер экрана: " + displaySize.x + " x " + displaySize.y); int RotatedPreviewWidth = ширина; int RotatedPreviewHeight = высота; int maxPreviewWidth = displaySize.x; int maxPreviewHeight = displaySize.y; int maxAllowedWidth = Math.min(displaySize.x, MAX_PREVIEW_WIDTH); int maxAllowedHeight = Math.min(displaySize.y, MAX_PREVIEW_HEIGHT); если (поменялись измерениями) { RotatedPreviewWidth = высота; RotatedPreviewHeight = ширина; maxPreviewWidth = displaySize.y; maxPreviewHeight = displaySize.x; } если (maxPreviewWidth > MAX_PREVIEW_WIDTH) { maxPreviewWidth = MAX_PREVIEW_WIDTH; } если (maxPreviewHeight > MAX_PREVIEW_HEIGHT) { maxPreviewHeight = MAX_PREVIEW_HEIGHT; } Log.d(TAG, "Размер повернутого предварительного просмотра 1: " + RotadPreviewWidth + " x " + RotadPreviewHeight); Log.d(TAG, "Максимальный размер предварительного просмотра 1: " + maxPreviewWidth + " x " + maxPreviewHeight); двойной аспектRatio = (двойной) RotatedPreviewWidth/rotatedPreviewHeight; intOptimalPreviewWidth = maxAllowedWidth; intOptimalPreviewHeight = (int) (optimalPreviewWidth/AspectRatio); если (optimalPreviewHeight > maxAllowedHeight) { оптимальнаяPreviewHeight = maxAllowedHeight; Log.d(ТЕГ, «Введено»); оптимальнаяPreviewWidth = (int) (optimalPreviewHeight * аспектRatio); } RotatedPreviewWidth = оптимальнаяPreviewWidth; RotatedPreviewHeight =OptimalPreviewHeight; Log.d(TAG, "Размер повернутого предварительного просмотра 2: " + RotadPreviewWidth + " x " + RotadPreviewHeight); Log.d(TAG, "Макс. размер предварительного просмотра 2: " + maxPreviewWidth + " x " + maxPreviewHeight); // Опасно, В.Р.! Попытка использовать слишком большой размер предварительного просмотра может выйти за пределы камеры. // ограничение пропускной способности шины, что приводит к великолепному предварительному просмотру, но хранению // данные для сбора мусора. mPreviewSize = ChooseOptimalSize(map.getOutputSizes(SurfaceTexture.class), RotatedPreviewWidth, RotatedPreviewHeight, maxAllowedWidth, maxAllowedHeight, самый большой); Log.d(TAG, String.format("Размер предварительного просмотра: (%d, %d)", mPreviewSize.getWidth(), mPreviewSize.getHeight())); // Мы подгоняем соотношение сторон TextView к выбранному нами размеру предварительного просмотра. int ориентация = getResources().getConfiguration().orientation; если (ориентация == Configuration.ORIENTATION_LANDSCAPE) { mTextureView.setAspectRatio( mPreviewSize.getWidth(), mPreviewSize.getHeight()); } еще { mTextureView.setAspectRatio( mPreviewSize.getHeight(), mPreviewSize.getWidth()); } mCameraId = идентификатор камеры; возвращаться; } } catch (CameraAccessException e) { е.printStackTrace(); } catch (NullPointerException e) { // В настоящее время NPE генерируется, когда Camera2API используется, но не поддерживается на // устройство, на котором работает этот код. ErrorDialog.newInstance(getString(R.string.camera_error)) .show(getChildFragmentManager(), FRAGMENT_DIALOG); } } fragment_camera2.xml:
Я пытаюсь создать экран предварительного просмотра с наложением круга поверх него. В соответствии с требованиями проекта экран предварительного просмотра должен быть достаточно большим, чтобы полностью вместить круг. В требованиях проекта также указано, что существуют максимальные размеры, которые никогда не могут быть превышены независимо от устройства из-за риска превышения ограничения пропускной способности шины камеры, что приводит к великолепным предварительным просмотрам, но к хранению данных захвата мусора.
Чтобы учесть это, я в основном сделал так, чтобы ширина экрана предварительного просмотра была установлена на максимальную ширину или на ширину экрана, если устройство недостаточно велико. Он получил те размеры, которые мне нужны для экрана предварительного просмотра, но он очень увеличен и размыт.
Я не знаю, как получить правильные размеры и сохранить хорошее качество камеры. Буду очень признателен за любую помощь в исправлении этой проблемы.
Соответствующие фрагменты кода:
AutoFitTextureView.java:
пакет edu.washington.cs.ubicomplab.camera2skeleton; импортировать android.content.Context; импортировать android.util.AttributeSet; импортировать android.view.TextureView; /** * {@link TextView}, который можно настроить под указанное соотношение сторон. */ публичный класс AutoFitTextureView расширяет TextView { частный int mRatioWidth = 0; частный int mRatioHeight = 0; public AutoFitTextureView (контекстный контекст) { это (контекст, ноль); } public AutoFitTextureView (контекст контекста, атрибуты AttributeSet) { это (контекст, атрибуты, 0); } public AutoFitTextureView (контекст контекста, атрибуты AttributeSet, int defStyle) { супер(контекст, атрибуты, defStyle); } /** * Устанавливает соотношение сторон для этого вида. Размер представления будет измеряться на основе соотношения * рассчитано по параметрам. Обратите внимание, что фактические размеры параметров не имеют значения, т.е. * есть, вызов setAspectRatio(2, 3) и setAspectRatio(4, 6) дает тот же результат. * * @param width Относительный горизонтальный размер * @param height Относительный размер по вертикали */ public void setAspectRatio (ширина int, высота int) { если (ширина < 0 || высота < 0) { throw new IllegalArgumentException("Размер не может быть отрицательным."); } mRatioWidth = ширина; mRatioHeight = высота; запросLayout(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int width = MeasureSpec.getSize(widthMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); if (0 == mRatioWidth || 0 == mRatioHeight) { setMeasuredDimension (ширина, высота); } еще { if (ширина < высота * mRatioWidth / mRatioHeight) { setMeasuredDimension (ширина, ширина * mRatioHeight / mRatioWidth); } еще { setMeasuredDimension (высота * mRatioWidth / mRatioHeight, высота); } } } } setUpCameraOutputs и выберите методы OptimalSize в Camera2Fragment.java:
/** * Учитывая {@code choice} из {@code Size}, поддерживаемых камерой, выберите наименьший из них, который * по крайней мере равен размеру соответствующего представления текстуры и не превышает размера * соответствующий максимальный размер и соотношение сторон которого соответствует указанному значению. Если такой размер * не существует, выберите самый большой, размер которого не превышает соответствующего максимального размера, * и соотношение сторон которого соответствует указанному значению. * * @param choice Список размеров, которые поддерживает камера для предполагаемого вывода. * сорт * @paramtextureViewWidth Ширина изображения текстуры относительно координаты датчика. * @paramtextureViewHeight Высота изображения текстуры относительно координаты датчика. * @param maxWidth Максимальная ширина, которую можно выбрать. * @param maxHeight Максимальная высота, которую можно выбрать. * @paramspectRatio Соотношение сторон * @return Оптимальный {@размер кода} или произвольный, если ни один из них не был достаточно большим. */ частный статический размер ChooseOptimalSize (Выбор размера [], inttextureViewWidth, inttextureViewHeight, int maxWidth, int maxHeight, SizespectRatio) { // Собираем поддерживаемые разрешения, по крайней мере такие же большие, как поверхность предварительного просмотра List bigEnough = новый ArrayList(); // Собираем поддерживаемые разрешения, которые меньше поверхности предварительного просмотра List notBigEnough = новый ArrayList(); int w = аспектRatio.getWidth(); int h = аспектRatio.getHeight(); для (вариант размера: выбор) { if (option.getWidth() = текстураViewHeight) { bigEnough.add (опция); } еще { notBigEnough.add (опция); } } } // Выбираем самый маленький из достаточно больших. Если нет никого достаточно большого, выберите // самый большой из недостаточно больших. если (bigEnough.size() > 0) { return Collections.min(bigEnough, new CompareSizesByArea()); } else if (notBigEnough.size() > 0) { return Collections.max(notBigEnough, new CompareSizesByArea()); } еще { Log.e(TAG, «Не удалось найти подходящий размер предварительного просмотра»); возврат выбора[0]; } } /** * Устанавливает переменные-члены, связанные с камерой. * * @param width Ширина доступного размера для предварительного просмотра камеры. * @param height Высота доступного размера для предварительного просмотра камеры. */ @SuppressWarnings («Подозрительная комбинация имен») Private void setUpCameraOutputs (ширина int, высота int) { Активность активности = getActivity(); Менеджер CameraManager = (CameraManager) Activity.getSystemService(Context.CAMERA_SERVICE); пытаться { for (String cameraId: Manager.getCameraIdList()) { КамераХарактеристики характеристики = менеджер.getCameraCharacteristics(cameraId); // В этом примере мы не используем фронтальную камеру. Целочисленное лицо = характеристики.get(CameraCharacteristics.LENS_FACING); if (лицом!= null && лицом == CameraCharacteristics.LENS_FACING_FRONT) { продолжать; } Карта StreamConfigurationMap = характеристики.get( CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); если (карта == ноль) { продолжать; } // Для захвата неподвижных изображений мы используем наибольший доступный размер. Наибольший размер = Collections.max( Arrays.asList(map.getOutputSizes(ImageFormat.YUV_420_888)), новый CompareSizesByArea()); mImageReader = ImageReader.newInstance(largest.getWidth(), крупнейших.getHeight(), ImageFormat.YUV_420_888, /*maxImages*/2); mImageReader.setOnImageAvailableListener( mOnImageAvailableListener, mBackgroundHandler); // Выясняем, нужно ли нам поменять размер, чтобы получить размер предварительного просмотра относительно датчика // координата. int displayRotation = Activity.getWindowManager().getDefaultDisplay().getRotation(); //без проверки константных условий mSensorOrientation = характеристики.get(CameraCharacteristics.SENSOR_ORIENTATION); логическое значение swappedDimensions = false; переключатель (displayRotation) { корпус Surface.ROTATION_0: чехол Surface.ROTATION_180: if (mSensorOrientation == 90 || mSensorOrientation == 270) { swappedDimensions = правда; } перерыв; чехол Surface.ROTATION_90: чехол Surface.ROTATION_270: if (mSensorOrientation == 0 || mSensorOrientation == 180) { swappedDimensions = правда; } перерыв; по умолчанию: Log.e(TAG, "Недопустимый поворот дисплея: " + displayRotation); } Point displaySize = новая точка(); Activity.getWindowManager().getDefaultDisplay().getSize(displaySize); Log.d(TAG, "Размер экрана: " + displaySize.x + " x " + displaySize.y); int RotatedPreviewWidth = ширина; int RotatedPreviewHeight = высота; int maxPreviewWidth = displaySize.x; int maxPreviewHeight = displaySize.y; int maxAllowedWidth = Math.min(displaySize.x, MAX_PREVIEW_WIDTH); int maxAllowedHeight = Math.min(displaySize.y, MAX_PREVIEW_HEIGHT); если (поменялись измерениями) { RotatedPreviewWidth = высота; RotatedPreviewHeight = ширина; maxPreviewWidth = displaySize.y; maxPreviewHeight = displaySize.x; } если (maxPreviewWidth > MAX_PREVIEW_WIDTH) { maxPreviewWidth = MAX_PREVIEW_WIDTH; } если (maxPreviewHeight > MAX_PREVIEW_HEIGHT) { maxPreviewHeight = MAX_PREVIEW_HEIGHT; } Log.d(TAG, "Размер повернутого предварительного просмотра 1: " + RotadPreviewWidth + " x " + RotadPreviewHeight); Log.d(TAG, "Максимальный размер предварительного просмотра 1: " + maxPreviewWidth + " x " + maxPreviewHeight); двойной аспектRatio = (двойной) RotatedPreviewWidth/rotatedPreviewHeight; intOptimalPreviewWidth = maxAllowedWidth; intOptimalPreviewHeight = (int) (optimalPreviewWidth/AspectRatio); если (optimalPreviewHeight > maxAllowedHeight) { оптимальнаяPreviewHeight = maxAllowedHeight; Log.d(ТЕГ, «Введено»); оптимальнаяPreviewWidth = (int) (optimalPreviewHeight * аспектRatio); } RotatedPreviewWidth = оптимальнаяPreviewWidth; RotatedPreviewHeight =OptimalPreviewHeight; Log.d(TAG, "Размер повернутого предварительного просмотра 2: " + RotadPreviewWidth + " x " + RotadPreviewHeight); Log.d(TAG, "Макс. размер предварительного просмотра 2: " + maxPreviewWidth + " x " + maxPreviewHeight); // Опасно, В.Р.! Попытка использовать слишком большой размер предварительного просмотра может выйти за пределы камеры. // ограничение пропускной способности шины, что приводит к великолепному предварительному просмотру, но хранению // данные для сбора мусора. mPreviewSize = ChooseOptimalSize(map.getOutputSizes(SurfaceTexture.class), RotatedPreviewWidth, RotatedPreviewHeight, maxAllowedWidth, maxAllowedHeight, самый большой); Log.d(TAG, String.format("Размер предварительного просмотра: (%d, %d)", mPreviewSize.getWidth(), mPreviewSize.getHeight())); // Мы подгоняем соотношение сторон TextView к выбранному нами размеру предварительного просмотра. int ориентация = getResources().getConfiguration().orientation; если (ориентация == Configuration.ORIENTATION_LANDSCAPE) { mTextureView.setAspectRatio( mPreviewSize.getWidth(), mPreviewSize.getHeight()); } еще { mTextureView.setAspectRatio( mPreviewSize.getHeight(), mPreviewSize.getWidth()); } mCameraId = идентификатор камеры; возвращаться; } } catch (CameraAccessException e) { е.printStackTrace(); } catch (NullPointerException e) { // В настоящее время NPE генерируется, когда Camera2API используется, но не поддерживается на // устройство, на котором работает этот код. ErrorDialog.newInstance(getString(R.string.camera_error)) .show(getChildFragmentManager(), FRAGMENT_DIALOG); } } fragment_camera2.xml:
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Как исправить размытый экран предварительного просмотра камеры [закрыто]
Anonymous » » в форуме Android - 0 Ответы
- 52 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Android: ориентация/поворот экрана для предварительного просмотра камеры
Anonymous » » в форуме Android - 0 Ответы
- 18 Просмотры
-
Последнее сообщение Anonymous
-