Skip to content

Instantly share code, notes, and snippets.

@st235
Last active March 16, 2024 16:01
Show Gist options
  • Save st235/615b4d92552eccf6af8eed154ad48f2d to your computer and use it in GitHub Desktop.
Save st235/615b4d92552eccf6af8eed154ad48f2d to your computer and use it in GitHub Desktop.
package github.com.st235;
import android.content.ContentResolver;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.net.Uri;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.exifinterface.media.ExifInterface;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
public class LocalUriLoader {
private static final String TAG = "LocalUriLoader";
private static final int MAX_DIMENSION = 1920;
@NonNull
private final ContentResolver contentResolver;
public LocalUriLoader(@NonNull ContentResolver contentResolver) {
this.contentResolver = contentResolver;
}
@Nullable
public Bitmap load(@NonNull Uri uri) {
try {
BitmapFactory.Options options = new BitmapFactory.Options();
InputStream inputStream = contentResolver.openInputStream(uri);
if (inputStream == null) {
return null;
}
options.inJustDecodeBounds = true;
options.inPreferredConfig = Bitmap.Config.RGB_565;
BitmapFactory.decodeStream(inputStream, /* outPadding= */ null, options);
inputStream.close();
inputStream = contentResolver.openInputStream(uri);
if (inputStream == null) {
return null;
}
options.inSampleSize = calculateInSampleSize(options, /* maxWidth= */ MAX_DIMENSION,
/* maxHeight= */ MAX_DIMENSION);
options.inJustDecodeBounds = false;
Bitmap bitmap = BitmapFactory.decodeStream(inputStream, /* outPadding= */ null, options);
inputStream.close();
if (bitmap == null) {
return null;
}
Matrix rotationMatrix = getCorrectBitmapRotation(contentResolver, uri);
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(),
rotationMatrix, true);
} catch (FileNotFoundException e) {
Log.w(TAG, "Cannot find uri: " + uri, e);
return null;
} catch (IOException e) {
Log.w(TAG, "Disk read/write error." , e);
return null;
}
}
private static int calculateInSampleSize(@NonNull BitmapFactory.Options options,
int maxWidth,
int maxHeight) {
int rawHeight = options.outHeight;
int rawWidth = options.outWidth;
int inSampleSize = 1;
if (rawHeight > maxHeight || rawWidth > maxWidth) {
int halfHeight = rawHeight / 2;
int halfWidth = rawWidth / 2;
while (halfHeight / inSampleSize >= maxHeight
&& halfWidth / inSampleSize >= maxWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
@NonNull
private static Matrix getCorrectBitmapRotation(@NonNull ContentResolver contentResolver,
@NonNull Uri uri) {
Matrix rotationMatrix = new Matrix();
InputStream inputStream = null;
try {
inputStream = contentResolver.openInputStream(uri);
} catch (FileNotFoundException e) {
Log.w(TAG, "Uri not found: " + uri, e);
return rotationMatrix;
}
if (inputStream == null) {
return rotationMatrix;
}
ExifInterface exifInterface;
try {
exifInterface = new ExifInterface(inputStream);
} catch (IOException e) {
Log.w(TAG, "Cannot read EXIF for " + uri, e);
return rotationMatrix;
}
int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch(orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
rotationMatrix.postRotate(90f);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotationMatrix.postRotate(180f);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotationMatrix.postRotate(270f);
break;
}
return rotationMatrix;
}
}
public class MainActivity extends AppCompatActivity {
private LocalUriLoader localUriLoader;
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
localUriLoader = new LocalUriLoader(getApplicationContext().getContentResolver());
...
}
private void processImage(Uri selectedImageUri) {
try {
sampledBitmap = localUriLoader.load(selectedImageUri);
imageView.setImageBitmap(sampledBitmap);
} catch (Exception e) {
Log.e(TAG, "Exception thrown: ",e);
}
}
...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment