У меня есть приложение Andriod, которое использует API Camera2 для сохранения изображений в галерее, оно работает и хорошо сохраняет изображения, но когда я беру три последовательных изображения без закрытия приложения, для сохранения третьего изображения требуется много времени, и я не надеваю ' Не хочу, чтобы сбережение заняло более 5 секунд. public void takePicture () {< /p>
try {
CameraManager manager = (CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraDevice.getId());
Size[] jpegSizes = Objects.requireNonNull(characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)).getOutputSizes(ImageFormat.JPEG);
int width = 640;
int height = 480;
if (jpegSizes != null && jpegSizes.length > 0) {
width = jpegSizes[0].getWidth();
height = jpegSizes[0].getHeight();
}
ImageReader reader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 1);
List outputSurfaces = new ArrayList(2);
outputSurfaces.add(reader.getSurface());
outputSurfaces.add(new Surface(binding.textUreView.getSurfaceTexture()));
final CaptureRequest.Builder captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
captureBuilder.addTarget(reader.getSurface());
captureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
// Orientation
int rotation = getActivity().getWindowManager().getDefaultDisplay().getRotation();
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));
// Set the zoom level to match the preview
Rect sensorArraySize = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
String zoomLevelString = getString(R.string.ZOOM_LEVEL);
float zoomLevel = Float.parseFloat(zoomLevelString);
assert sensorArraySize != null;
int cropW = (int) (sensorArraySize.width() / zoomLevel);
int cropH = (int) (sensorArraySize.height() / zoomLevel);
int cropX = (sensorArraySize.width() - cropW) / 2;
int cropY = (sensorArraySize.height() - cropH) / 2;
Rect zoomRect = new Rect(cropX, cropY, cropX + cropW, cropY + cropH);
captureBuilder.set(CaptureRequest.SCALER_CROP_REGION, zoomRect);
ImageReader.OnImageAvailableListener readerListener = imageReaderListener -> {
try (Image image = imageReaderListener.acquireLatestImage()) {
if (image == null) {
showUserMessage(getString(R.string.message_image_capture_failed));
return;
}
// Extract image bytes
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.capacity()];
buffer.get(bytes);
userLocation.getLastLocation(location -> {
// Retrieve location data
double latitude = location.getLatitude();
double longitude = location.getLongitude();
try {
// Save the image with location metadata (if supported by the method)
String savedFileName;
// Save image with location metadata using a newer API for Android R and above
savedFileName = saveImageWithLocation(bytes, latitude, longitude);
// Notify the main activity with the saved image path
cameraViewModel.setImageFinalName(savedFileName);
// Show a message to the user about the successful save operation
showUserMessage(getString(R.string.message_image_save_successful));
} catch (IOException e) {
// Handle exceptions during file saving
showUserMessage(getString(R.string.message_image_save_failed));
cameraViewModel.setCameraException(e);
}
});
} catch (Exception e) {
// Handle any exceptions that occur during image acquisition or processing
showUserMessage(getString(R.string.message_image_processing_error));
cameraViewModel.setCameraException(e);
}
};
reader.setOnImageAvailableListener(readerListener, mBackgroundHandler);
final CameraCaptureSession.CaptureCallback captureListener = new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
createCameraPreview();
}
};
cameraDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
try {
session.capture(captureBuilder.build(), captureListener, mBackgroundHandler);
}catch (CameraAccessException e) {
// Show a dialog for CameraAccessException
showErrorDialog(getString(R.string.error_title_camera), getString(R.string.camera_access_exception, e.getMessage()));
} catch (IllegalStateException e) {
// Show a dialog for IllegalStateException
showErrorDialog(getString(R.string.error_title_runtime), getString(R.string.camera_runtime_error_illegal_state_exception, e.getMessage()));
}
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
session.close();
}
}, mBackgroundHandler);
} catch (CameraAccessException e) {
throw new RuntimeException(e);
}
}
/**
* Show a message to the user using a Toast or Dialog.
*
* @param message The message to be displayed to the user.
*/
private void showUserMessage(String message) {
if (getActivity() != null) {
Toast.makeText(getActivity(), message, Toast.LENGTH_SHORT).show();
}
}
/**
* @returnthe image name
*/
@SuppressLint("SimpleDateFormat")
private String generateCapturedImageName() {
Date date = new Date();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd-kk-mm-ss");
String newPicFile = df.format(date);
return userFullName +"_"+ newPicFile + ".jpg";
}
private String saveImageWithLocation(byte[] bytes, double latitude, double longitude) throws IOException {
// Generate a single filename
String fileName = generateCapturedImageName();
// Ensure external directory exists
File directory = ensureDirectoryExists();
// Create the file
File fileFinal = new File(directory, fileName);
// Store the filename and directory in the ViewModel
cameraViewModel.setImageFileName(fileName); // Store the filename
cameraViewModel.setFileDirectory(directory); // Store the directory
// Write the image data to the file
try (OutputStream output = new FileOutputStream(fileFinal)) {
output.write(bytes);
}
// Set EXIF metadata for GPS location
ExifInterface exif = new ExifInterface(fileFinal.getAbsolutePath());
userLocation.setExifGpsData(exif, latitude, longitude);
exif.saveAttributes();
// Notify MediaScanner
MediaScannerConnection.scanFile(
getActivity().getApplicationContext(),
new String[]{fileFinal.getAbsolutePath()},
null,
(path, uri) -> Log.d(TAG, getString(R.string.Image_scanned_into_gallery) + path)
);
Log.d("FileDebug", "File created at: " + fileFinal.getAbsolutePath());
return fileFinal.getAbsolutePath();
}
< /code>
Я попытался создать разные потоки и изменить максимум считывателя изображения с 2 до 5, но это не сработало. Я также попытался взять на себя очистку буфера изображения, но не нашел решение.
Подробнее здесь: https://stackoverflow.com/questions/794 ... essive-ima
Сохранение изображений в галерею в Android Studio задержки после третьего последующего изображения ⇐ Android
Форум для тех, кто программирует под Android
1739281366
Anonymous
У меня есть приложение Andriod, которое использует API Camera2 для сохранения изображений в галерее, оно работает и хорошо сохраняет изображения, но когда я беру три последовательных изображения без закрытия приложения, для сохранения третьего изображения требуется много времени, и я не надеваю ' Не хочу, чтобы сбережение заняло более 5 секунд. public void takePicture () {< /p>
try {
CameraManager manager = (CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraDevice.getId());
Size[] jpegSizes = Objects.requireNonNull(characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)).getOutputSizes(ImageFormat.JPEG);
int width = 640;
int height = 480;
if (jpegSizes != null && jpegSizes.length > 0) {
width = jpegSizes[0].getWidth();
height = jpegSizes[0].getHeight();
}
ImageReader reader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 1);
List outputSurfaces = new ArrayList(2);
outputSurfaces.add(reader.getSurface());
outputSurfaces.add(new Surface(binding.textUreView.getSurfaceTexture()));
final CaptureRequest.Builder captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
captureBuilder.addTarget(reader.getSurface());
captureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
// Orientation
int rotation = getActivity().getWindowManager().getDefaultDisplay().getRotation();
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));
// Set the zoom level to match the preview
Rect sensorArraySize = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
String zoomLevelString = getString(R.string.ZOOM_LEVEL);
float zoomLevel = Float.parseFloat(zoomLevelString);
assert sensorArraySize != null;
int cropW = (int) (sensorArraySize.width() / zoomLevel);
int cropH = (int) (sensorArraySize.height() / zoomLevel);
int cropX = (sensorArraySize.width() - cropW) / 2;
int cropY = (sensorArraySize.height() - cropH) / 2;
Rect zoomRect = new Rect(cropX, cropY, cropX + cropW, cropY + cropH);
captureBuilder.set(CaptureRequest.SCALER_CROP_REGION, zoomRect);
ImageReader.OnImageAvailableListener readerListener = imageReaderListener -> {
try (Image image = imageReaderListener.acquireLatestImage()) {
if (image == null) {
showUserMessage(getString(R.string.message_image_capture_failed));
return;
}
// Extract image bytes
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.capacity()];
buffer.get(bytes);
userLocation.getLastLocation(location -> {
// Retrieve location data
double latitude = location.getLatitude();
double longitude = location.getLongitude();
try {
// Save the image with location metadata (if supported by the method)
String savedFileName;
// Save image with location metadata using a newer API for Android R and above
savedFileName = saveImageWithLocation(bytes, latitude, longitude);
// Notify the main activity with the saved image path
cameraViewModel.setImageFinalName(savedFileName);
// Show a message to the user about the successful save operation
showUserMessage(getString(R.string.message_image_save_successful));
} catch (IOException e) {
// Handle exceptions during file saving
showUserMessage(getString(R.string.message_image_save_failed));
cameraViewModel.setCameraException(e);
}
});
} catch (Exception e) {
// Handle any exceptions that occur during image acquisition or processing
showUserMessage(getString(R.string.message_image_processing_error));
cameraViewModel.setCameraException(e);
}
};
reader.setOnImageAvailableListener(readerListener, mBackgroundHandler);
final CameraCaptureSession.CaptureCallback captureListener = new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
createCameraPreview();
}
};
cameraDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
try {
session.capture(captureBuilder.build(), captureListener, mBackgroundHandler);
}catch (CameraAccessException e) {
// Show a dialog for CameraAccessException
showErrorDialog(getString(R.string.error_title_camera), getString(R.string.camera_access_exception, e.getMessage()));
} catch (IllegalStateException e) {
// Show a dialog for IllegalStateException
showErrorDialog(getString(R.string.error_title_runtime), getString(R.string.camera_runtime_error_illegal_state_exception, e.getMessage()));
}
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
session.close();
}
}, mBackgroundHandler);
} catch (CameraAccessException e) {
throw new RuntimeException(e);
}
}
/**
* Show a message to the user using a Toast or Dialog.
*
* @param message The message to be displayed to the user.
*/
private void showUserMessage(String message) {
if (getActivity() != null) {
Toast.makeText(getActivity(), message, Toast.LENGTH_SHORT).show();
}
}
/**
* @returnthe image name
*/
@SuppressLint("SimpleDateFormat")
private String generateCapturedImageName() {
Date date = new Date();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd-kk-mm-ss");
String newPicFile = df.format(date);
return userFullName +"_"+ newPicFile + ".jpg";
}
private String saveImageWithLocation(byte[] bytes, double latitude, double longitude) throws IOException {
// Generate a single filename
String fileName = generateCapturedImageName();
// Ensure external directory exists
File directory = ensureDirectoryExists();
// Create the file
File fileFinal = new File(directory, fileName);
// Store the filename and directory in the ViewModel
cameraViewModel.setImageFileName(fileName); // Store the filename
cameraViewModel.setFileDirectory(directory); // Store the directory
// Write the image data to the file
try (OutputStream output = new FileOutputStream(fileFinal)) {
output.write(bytes);
}
// Set EXIF metadata for GPS location
ExifInterface exif = new ExifInterface(fileFinal.getAbsolutePath());
userLocation.setExifGpsData(exif, latitude, longitude);
exif.saveAttributes();
// Notify MediaScanner
MediaScannerConnection.scanFile(
getActivity().getApplicationContext(),
new String[]{fileFinal.getAbsolutePath()},
null,
(path, uri) -> Log.d(TAG, getString(R.string.Image_scanned_into_gallery) + path)
);
Log.d("FileDebug", "File created at: " + fileFinal.getAbsolutePath());
return fileFinal.getAbsolutePath();
}
< /code>
Я попытался создать разные потоки и изменить максимум считывателя изображения с 2 до 5, но это не сработало. Я также попытался взять на себя очистку буфера изображения, но не нашел решение.
Подробнее здесь: [url]https://stackoverflow.com/questions/79429077/saving-images-to-gallery-in-andriod-studio-delays-after-the-third-successive-ima[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия