From c6be28df562dfbd26396249904a7a0c4730ac6a1 Mon Sep 17 00:00:00 2001 From: Olga Miller Date: Sat, 4 Mar 2023 17:26:19 +0100 Subject: [PATCH] Removed image size limit by replacing BitmapFactory.decodeStream with BitmapFactory.decodeByteArray, simplified the code a bit --- .../main/java/om/sstvencoder/CropView.java | 57 ++++++++++++------- .../java/om/sstvencoder/MainActivity.java | 37 +++++------- 2 files changed, 48 insertions(+), 46 deletions(-) diff --git a/app/src/main/java/om/sstvencoder/CropView.java b/app/src/main/java/om/sstvencoder/CropView.java index 08b61ce..014ab7b 100644 --- a/app/src/main/java/om/sstvencoder/CropView.java +++ b/app/src/main/java/om/sstvencoder/CropView.java @@ -182,7 +182,7 @@ public class CropView extends AppCompatImageView { invalidate(); } - public void setBitmap(@NonNull InputStream stream) throws IOException, IllegalArgumentException { + public void setBitmap(@NonNull InputStream stream) throws Exception { mImageOK = false; mOrientation = 0; recycle(); @@ -190,35 +190,48 @@ public class CropView extends AppCompatImageView { invalidate(); } - private void loadImage(InputStream stream) throws IOException, IllegalArgumentException { - // app6 + exif - int bufferBytes = 1048576; - if (!stream.markSupported()) - stream = new BufferedInputStream(stream, bufferBytes); - stream.mark(bufferBytes); + private void loadImage(InputStream stream) throws Exception { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; - BitmapFactory.decodeStream(new BufferedInputStream(stream), null, options); - stream.reset(); + byte[] streamBytes = null; + String errorMessage = null; + try { + int length = stream.available(); + if (length > 0) { + streamBytes = new byte[length]; + if (length == stream.read(streamBytes, 0, streamBytes.length)) { + BitmapFactory.decodeByteArray(streamBytes, 0, streamBytes.length, options); + } + else + streamBytes = null; + } + } catch (Exception ex) { + errorMessage = ex.getMessage(); + streamBytes = null; + } + mImageWidth = options.outWidth; mImageHeight = options.outHeight; - if (mImageWidth * mImageHeight < 1024 * 1024) { - mCacheBitmap = BitmapFactory.decodeStream(stream); - mSmallImage = true; - } else { - mRegionDecoder = BitmapRegionDecoder.newInstance(stream, true); - mCacheRect.setEmpty(); - mSmallImage = false; + if (streamBytes != null && mImageWidth > 0 && mImageHeight > 0) { + mSmallImage = mImageWidth * mImageHeight < 1024 * 1024; + if (mSmallImage) { + mCacheBitmap = BitmapFactory.decodeByteArray(streamBytes, 0, streamBytes.length, null); + } else { + mRegionDecoder = BitmapRegionDecoder.newInstance(streamBytes, 0, streamBytes.length, true); + mCacheRect.setEmpty(); + } } if (mCacheBitmap == null && mRegionDecoder == null) { - String size = options.outWidth + "x" + options.outHeight; - String message = "Stream could not be decoded. Image size: " + size; - if (mImageWidth <= 0 || mImageHeight <= 0) - throw new IllegalArgumentException(message); - else - throw new IOException(message); + String message = errorMessage; + if (message == null) { + message = "Stream could not be decoded."; + if (mImageWidth > 0 && mImageHeight > 0) { + message += " Image size: " + mImageWidth + "x" + mImageHeight; + } + } + throw new Exception(message); } mImageOK = true; diff --git a/app/src/main/java/om/sstvencoder/MainActivity.java b/app/src/main/java/om/sstvencoder/MainActivity.java index 370020a..d3f840e 100644 --- a/app/src/main/java/om/sstvencoder/MainActivity.java +++ b/app/src/main/java/om/sstvencoder/MainActivity.java @@ -119,41 +119,30 @@ public class MainActivity extends AppCompatActivity { // Set verbose to false for any Uri that might have expired (e.g. shared from browser). private boolean loadImage(Uri uri, boolean verbose) { + boolean succeeded = false; ContentResolver resolver = getContentResolver(); - InputStream stream = null; if (uri != null) { - mSettings.setImageUri(uri); try { - stream = resolver.openInputStream(uri); + InputStream stream = resolver.openInputStream(uri); + if (stream != null) + mCropView.setBitmap(stream); + succeeded = true; } catch (Exception ex) { // e.g. FileNotFoundException, SecurityException if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isPermissionException(ex) && needsRequestReadPermission()) { requestReadPermission(REQUEST_LOAD_IMAGE_PERMISSION); - return false; } - showFileNotLoadedMessage(ex, verbose); + else + showFileNotLoadedMessage(ex, verbose); } } - if (stream == null || !loadImage(stream, resolver, uri)) { + if (succeeded) { + mCropView.rotateImage(getOrientation(resolver, uri)); + mSettings.setImageUri(uri); + } + else setDefaultBitmap(); - return false; - } - return true; - } - - private boolean loadImage(InputStream stream, ContentResolver resolver, Uri uri) { - try { - mCropView.setBitmap(stream); - } catch (IllegalArgumentException ex) { - Toast.makeText(this, ex.getMessage(), Toast.LENGTH_LONG).show(); - return false; - } catch (Exception ex) { - String s = Utility.createMessage(ex) + "\n\n" + uri; - showErrorMessage(getString(R.string.load_img_err_title), ex.getMessage(), s); - return false; - } - mCropView.rotateImage(getOrientation(resolver, uri)); - return true; + return succeeded; } private void setDefaultBitmap() {