#android #image-rotation
#Android #вращение изображения
Вопрос:
У меня возникли проблемы с определением исключения, которое генерируется конструктором ExifInterface при попытке инициализировать экземпляр интерфейса exif с помощью пути к файлу.
ОБНОВЛЕНО Пожалуйста, ознакомьтесь с подробным кодом ниже по запросу.
Функция загрузки файлов
public void downloadAndSaveFile(String url, String directoryId, String fileName) {
HttpURLConnection conn = null;
try {
Log.d(TAG, "DownloadFileTask url : " url);
conn = getGETConnection(url);
conn.setRequestProperty("Accept", "application/json");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Authorization", "Bearer " MY_AUTH_TOKEN);
conn.connect();
File file = new File(FileTools.getCacheFileLocation(fileName, directoryId));
FileOutputStream fileOutput = new FileOutputStream(file);
InputStream inputStream = (InputStream) conn.getInputStream();
byte[] buffer = new byte[1024 * 1024];
int bufferLength = 0;
while ((bufferLength = inputStream.read(buffer)) > 0) {
fileOutput.write(buffer, 0, bufferLength);
}
fileOutput.close();
inputStream.close();
Log.d(TAG, "Download successful. Downloaded File : " file.getAbsolutePath());
// Generate thumbnail and encrypt the file and thumbnail
***String thumbnailPath = FileTools.cacheThumbnail(file, file.getName(), directoryId);***
if (thumbnailPath != null amp;amp; !thumbnailPath.isEmpty()) {
// Encrypt the file
try {
FileTools.SaveFileEncrypted(file, directoryId);
} catch (Exception e) {
e.printStackTrace();
// Delete the file
file.delete();
}
} else {
// Delete the file
file.delete();
}
} catch (Exception e) {
Log.d(TAG, "Exception while downloading file");
e.printStackTrace();
} finally {
if (conn != null) {
conn.disconnect();
}
}
}
Функция FileTools.cacheThumbnail
public static String cacheThumbnail(File file, String fileName, String chatId) {
Log.d(TAG, "cacheThumbnail original File path : " file.getAbsolutePath());
Log.d(TAG, "cacheThumbnail original File exists : " file.exists());
Log.d(TAG, "cacheThumbnail original file size : " file.length());
String thumbName = String.format("thumb-%s.jpg", fileName);
File fileThumb = new File(FileTools.getMediaCachePath(chatId), thumbName);
ByteArrayOutputStream out = null;
try {
out = new ByteArrayOutputStream();
BitmapFactory.Options options = new BitmapFactory.Options();
Bitmap image = ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile(file.toURI().getPath(), options), 256, 256, ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
// Thumbnail generation for the image failed. It is a video file. Generate
// thumbnail for the video file
if (image == null) {
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
try {
retriever.setDataSource(FileTools.getFileInputStreamFromStorage(file).getFD());
// Generate thumbnail from a frame that is 5% deep into the video
String time = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
long timeInMillisec = Long.parseLong(time);
long durationMicroSec = timeInMillisec * 1000;
long thumbnailDepth = (long) (durationMicroSec * (0.15f));
image = retriever.getFrameAtTime(thumbnailDepth, MediaMetadataRetriever.OPTION_CLOSEST);
image = ThumbnailUtils.extractThumbnail(image, 256, 256, ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
} catch (IllegalArgumentException ex) {
Log.e(TAG, ex.getMessage());
image = null;
} catch (RuntimeException ex) {
Log.e(TAG, ex.getMessage());
image = null;
} catch (IOException e) {
image = null;
Log.e(TAG, e.getMessage());
}
}
// Could not generate a thumbnail. Probably a corrupt/bad file
if (image == null) {
return null;
}
***image = Utilities.orientBitmap(file.getAbsolutePath(), image);***
image.compress(Bitmap.CompressFormat.JPEG, 80, out);
out.close();
FileTools.SaveFileEncrypted(fileThumb, out.toByteArray());
return fileThumb.toURI().getPath();
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
try {
if (out != null) {
out.close();
}
} catch (Exception ignore) {
}
}
}
Функции orientBitmap и rotateBitmap функционируют
public static Bitmap orientBitmap(String filePath, Bitmap bitmap) throws IOException {
Log.d(TAG, "orientBitmap FilePath : " filePath);
File file = new File(filePath);
Log.d(TAG, "orientBitmap File exists : " file.exists());
ExifInterface exifInterface = new ExifInterface(filePath);
Log.d(TAG, "After exception");
int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
Log.d(TAG, "Thumb orientation : " orientation);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
bitmap = rotateBitmap(bitmap, 90);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
bitmap = rotateBitmap(bitmap, 180);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
bitmap = rotateBitmap(bitmap, 270);
break;
}
return bitmap;
}
public static Bitmap rotateBitmap(Bitmap source, float angle) {
Matrix matrix = new Matrix();
matrix.postRotate(angle);
return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
}
I am updating the stack traces by posting stack trace for when trying to generate the thumbnail of a mp4 file and png file.
Stack trace for mp4 file.
D/DownloadFileClass: downloadAndSaveFile url : example.com/media/download/568405
D/DownloadFileClass: Download successful. Downloaded File : /data/user/0/com.mypackage.myapp/cache/userhash/79640/media/MP4_20161017_134641.mp4
D/FileTools: cacheThumbnail original File path : /data/user/0/com.mypackage.myapp/cache/userhash/79640/media/MP4_20161017_134641.mp4
D/FileTools: cacheThumbnail original File exists : true
D/FileTools: cacheThumbnail original file size : 6434816
D/skia: --- SkImageDecoder::Factory returned null
D/Utilities: orientBitmap FilePath : /data/user/0/com.mypackage.myapp/cache/userhash/79640/media/MP4_20161017_134641.mp4
D/Utilities: orientBitmap File exists : true
W/ExifInterface: Invalid image.
java.io.IOException: Invalid marker: 0
at android.media.ExifInterface.getJpegAttributes(ExifInterface.java:1600)
at android.media.ExifInterface.loadAttributes(ExifInterface.java:1339)
at android.media.ExifInterface.<init>(ExifInterface.java:1057)
at com.mypackage.helpers.Utilities.orientBitmap(Utilities.java:85)
at com.mypackage.fileio.FileTools.cacheThumbnail(FileTools.java:700)
at com.mypackage.coreapi.DownloadFileClass$downloadAndSaveFile(DownloadFileClass.java:215)
at com.mypackage.coreapi.DownloadFileClass$downloadAndSaveFile(DownloadFileClass.java:113)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
D/Utilities: After exception
D/Utilities: Thumb orientation : 0
D/FileTools: Save file to : /data/user/0/com.mypackage.myapp/cache/userhash/79640/media/MP4_20161017_134641.mp4
D/EncryptedFileTools: ......Final saved file path...... : /data/user/0/com.mypackage.myapp/cache/userhash/79640/media/encryptPlaceHolder
Трассировка стека для файла png
D/DownloadFileClass: downloadAndSaveFile url : example.com/media/download/568406
D/DownloadFileClass: Download successful. Downloaded File : /data/user/0/com.mypackage.myapp/cache/userhash/79640/media/PNG_20161017_134748.png
D/FileTools: cacheThumbnail original File path : /data/user/0/com.mypackage.myapp/cache/userhash/79640/media/PNG_20161017_134748.png
D/FileTools: cacheThumbnail original File exists : true
D/FileTools: cacheThumbnail original file size : 92160
D/Utilities: orientBitmap FilePath : /data/user/0/com.mypackage.myapp/cache/userhash/79640/media/PNG_20161017_134748.png
D/Utilities: orientBitmap File exists : true
W/ExifInterface: Invalid image.
java.io.IOException: Invalid marker: 89
at android.media.ExifInterface.getJpegAttributes(ExifInterface.java:1600)
at android.media.ExifInterface.loadAttributes(ExifInterface.java:1339)
at android.media.ExifInterface.<init>(ExifInterface.java:1057)
at com.mypackage.helpers.Utilities.orientBitmap(Utilities.java:85)
at com.mypackage.fileio.FileTools.cacheThumbnail(FileTools.java:700)
at com.mypackage.coreapi.DownloadFileClass$downloadAndSaveFile(DownloadFileClass.java:215)
at com.mypackage.coreapi.DownloadFileClass$downloadAndSaveFile(DownloadFileClass.java:113)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
D/Utilities: After exception
D/Utilities: Thumb orientation : 0
D/FileTools: Save file to : /data/user/0/com.mypackage.myapp/cache/userhash/79640/media/PNG_20161017_134748.png
D/EncryptedFileTools: ......Final saved file path...... : /data/user/0/com.mypackage.myapp/cache/userhash/79640/media/encryptPlaceHolder
Запутанная часть заключается в том, что я не получаю это исключение при запуске приложения на моем Samsung Galaxy S4 с Android 4.4.4, но я всегда получаю его при запуске на моем Samsung Galaxy S5 с Android 6.0.1. Я также получаю эту ошибку в эмуляторе с Android 7.0. Я не уверен, какустраните эту проблему.
Пожалуйста, ознакомьтесь с прилагаемым снимком экрана разрешений. Разрешенные разрешения
Я добавил запрошенную информацию. Пожалуйста, дайте мне знать, если потребуется дополнительная информация. Я раньше не работал с ExifTags, поэтому, пожалуйста, потерпите меня. Еще раз спасибо.
Комментарии:
1. У вас есть доступ к файлу? Android 6.0 требует, чтобы вы запрашивали разрешения на внешнее хранилище во время выполнения, если вы нацелены на API 23 или выше
2. @ianhanniballake Спасибо за ваш ответ. У меня включены все разрешения. Я добавил снимок экрана страницы разрешений для вашей справки. Пожалуйста, дайте мне знать, если вам нужны дополнительные сведения.
3. какой путь вы передаете методу?? Также убедитесь, что файл существует
4. Я предполагаю, что
filePath
это не фактический путь к файловой системе. Пожалуйста, покажите код, в котором вы получаете это значение.5. В основном это хорошо представленный вопрос. Одна корректировка, о которой я бы попросил, заключается в том, что если ваши журналы имеют большой отступ вправо, пожалуйста, сдвиньте их влево, чтобы читателям не нужно было прокручивать их, чтобы прочитать их, спасибо.
Ответ №1:
Я обнаружил проблему с моим кодом выше. По-видимому, я пытался прочитать теги EXIF непосредственно из файлов mp4 и png. После поиска немного больше о тегах EXIF я обнаружил, что теги EXIF доступны только с файлами JPEG. Итак, решение моей проблемы заключалось в том, чтобы сначала создать изображение в формате JPEG из файла mp4 / png, а затем попытаться прочитать теги EXIF из этого файла JPEF. Это устранило проблему, и я больше не получаю исключение.
Спасибо всем, что указали мне решение.
Комментарии:
1. Как вы устранили проблему, можете ли вы объяснить, пожалуйста?
2. @praneethkumar Как я упоминал выше, я пытался прочитать теги EXIF непосредственно из файлов mp4 / png. Поскольку теги EXIF связаны только с файлами JPEG, я получал эту ошибку, когда пытался прочитать их из файла mp4 / png. Я предотвратил ошибку, сначала создав JPEG из файла mp4 / png, а затем попытавшись прочитать теги EXIF из файла JPEG. Этот подход предотвратит ошибку, но я не верю, что вы получите какую-либо информацию EXIF из файла JPEG, который был создан из mp4 / png, если вы явно не зададите значения EXIF для файла JPEG после его создания из файла mp4 / png.