Capturing images crashing on HTC devices - java

Hi I am developing a app that captures images and email it capturing the images is working fine on Samsung galaxy and Sony Ericsson xperia but it's not working on HTC devices anyone know a reason why ?? here is my code for capturing images
try {
String fileName = Image_name+".jpg";
//create parameters for Intent with filename
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, fileName);
values.put(MediaStore.Images.Media.DESCRIPTION,"Image capture by camera");
//imageUri is the current activity attribute, define and save it for later usage (also in onSaveInstanceState)
outuri = getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//outuri = Uri.fromFile(photo);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outuri);
cameraIntent.putExtra("return-data", true);
startActivityForResult(cameraIntent, 2);
} catch (Exception e) {
Toast.makeText(preview.this, ""+e, Toast.LENGTH_LONG).show();
}
and here is code that I use to retrieve images
path = convertImageUriToFile(outuri, preview.this).getAbsolutePath();
arr.add(path);
try {
bitmap = getImage(path);
public static File convertImageUriToFile (Uri imageUri, Activity activity) {
Cursor cursor = null;
try {
String [] proj={MediaStore.Images.Media.DATA, MediaStore.Images.Media._ID, MediaStore.Images.ImageColumns.ORIENTATION};
cursor = activity.managedQuery(imageUri, proj, // Which columns to return
null, // WHERE clause; which rows to return (all rows)
null, // WHERE clause selection arguments (none)
null); // Order-by clause (ascending by name)
int file_ColumnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
int orientation_ColumnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.ORIENTATION);
if (cursor.moveToFirst()) {
String orientation = cursor.getString(orientation_ColumnIndex);
return new File(cursor.getString(file_ColumnIndex));
}
return null;
} finally {
if (cursor != null) {
cursor.close();
}
}
}
public Bitmap getImage(String path) throws IOException
{
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
Bitmap targetBitmap=null;
int srcWidth = options.outWidth;
int srcHeight = options.outHeight;
int[] newWH = new int[2];
newWH[0] = 1024;
newWH[1] = (1024*srcHeight)/srcWidth;
int inSampleSize = 1;
while(srcWidth / 2 > newWH[0]){
srcWidth /= 2;
srcHeight /= 2;
inSampleSize *= 2;
}
// float desiredScale = (float) newWH[0] / srcWidth;
// Decode with inSampleSize
options.inJustDecodeBounds = false;
options.inDither = false;
options.inSampleSize = inSampleSize;
options.inScaled = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap sampledSrcBitmap = BitmapFactory.decodeFile(path,options);
ExifInterface exif = new ExifInterface(path);
String s=exif.getAttribute(ExifInterface.TAG_ORIENTATION);
System.out.println("Orientation>>>>>>>>>>>>>>>>>>>>"+s);
Matrix matrix = new Matrix();
float rotation = rotationForImage(preview.this, Uri.fromFile(new File(path)));
if (rotation != 0f) {
matrix.preRotate(rotation);
}
int newh = ( w * sampledSrcBitmap.getHeight() ) /sampledSrcBitmap.getWidth();
Bitmap r=Bitmap.createScaledBitmap(sampledSrcBitmap, w, newh, true);
Bitmap resizedBitmap = Bitmap.createBitmap(
r, 0, 0, w, newh, matrix, true);
return resizedBitmap;
}
}

well, there's a known bug in the Intent.putExtra(MediaStore.EXTRA_OUTPUT) and it causes a crash in the app.
check out the answer I got when asking the same question: https://stackoverflow.com/a/10613299/1056359

Related

Compressing multiple images before uploading them to firebase android

I am working on application users have to upload multiple images. Now the problem I am facing is their size. As users can upload multiple images it takes a lot of time to upload them through the application because of their heavy size which users do not like and also make my application and database heavy. Can you please guide me on how can I compress multiple images before uploading them to firebase?
CODE TO COMPRESS IMAGES
galleryResultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
#Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() == RESULT_OK && null != result.getData() ) {
if (result.getData().getClipData() != null) {
int countofImages = result.getData().getClipData().getItemCount();
//this part is to select multiple images
for (int i = 0; i < countofImages; i++) {
if (uri.size() < 11) {
Uri imageuri = result.getData().getClipData().getItemAt(i).getUri();
imageList.add(new CustomModel(getfilename(imageuri), imageuri));
} else {
Toast.makeText(getContext(), "Can't select more than 11 images", Toast.LENGTH_SHORT).show();
}
}
//then notify the adapter
adapter.notifyDataSetChanged();
rentSell3Binding.totalphotos.setText("Photos (" + imageList.size() + ")");
}
//this part is to select single image
else
{
if (uri.size()<11) {
Uri imageuri = result.getData().getData();
//and add the code to arryalist
imageList.add(new CustomModel(getfilename(imageuri), imageuri));
}else
{
Toast.makeText(getContext(), "Can't select more than 11 images", Toast.LENGTH_SHORT).show();
}
//notify the adapter
adapter.notifyDataSetChanged();
rentSell3Binding.totalphotos.setText("Photos (" + imageList.size() + ")");
}
}else
{
Toast.makeText(getContext(), "You haven't selected any images", Toast.LENGTH_SHORT).show();
}
}
});
MODEL CLASS
public class CustomModel {
String imageName;
Uri imageURI;
public CustomModel(String imageName, Uri imageURI) {
this.imageName = imageName;
this.imageURI = imageURI;
}
public String getImageName() {
return imageName;
}
public void setImageName(String imageName) {
this.imageName = imageName;
}
public Uri getImageURI() {
return imageURI;
}
public void setImageURI(Uri imageURI) {
this.imageURI = imageURI;
}
}
Throwing exception
null pointer exception on the line File file = new File(SiliCompressor.with(getContext()).compress(FileUtils.getPath(getContext(), imageuri), new File(getContext().getCacheDir(), "temp")));
yup, you can compress your image file by the following function
#Throws(IOException::class)
fun File.compressImage(
reqWidth: Float,
reqHeight: Float,
compressFormat: Bitmap.CompressFormat,
quality: Int,
destinationPath: String
): File {
var fileOutputStream: FileOutputStream? = null
val file = File(destinationPath).parentFile ?: return File(destinationPath)
if (!file.exists()) {
file.mkdirs()
}
try {
fileOutputStream = FileOutputStream(destinationPath)
// write the compressed bitmap at the destination specified by destinationPath.
decodeSampledBitmapFromFile(this, reqWidth, reqHeight)?.compress(
compressFormat,
quality,
fileOutputStream
)
} finally {
if (fileOutputStream != null) {
fileOutputStream.flush()
fileOutputStream.close()
}
}
return File(destinationPath)
}
#Throws(IOException::class)
private fun decodeSampledBitmapFromFile(
imageFile: File,
reqWidth: Float,
reqHeight: Float
): Bitmap? {
// First decode with inJustDecodeBounds=true to check dimensions
val options = BitmapFactory.Options()
options.inJustDecodeBounds = true
var bmp: Bitmap? = BitmapFactory.decodeFile(imageFile.absolutePath, options)
var actualHeight = options.outHeight
var actualWidth = options.outWidth
var imgRatio = actualWidth.toFloat() / actualHeight.toFloat()
val maxRatio = reqWidth / reqHeight
if (actualHeight > reqHeight || actualWidth > reqWidth) {
// If Height is greater
when {
imgRatio < maxRatio -> {
imgRatio = reqHeight / actualHeight
actualWidth = (imgRatio * actualWidth).toInt()
actualHeight = reqHeight.toInt()
} // If Width is greater
imgRatio > maxRatio -> {
imgRatio = reqWidth / actualWidth
actualHeight = (imgRatio * actualHeight).toInt()
actualWidth = reqWidth.toInt()
}
else -> {
actualHeight = reqHeight.toInt()
actualWidth = reqWidth.toInt()
}
}
}
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight)
options.inJustDecodeBounds = false
if (bmp != null && canUseForInBitmap(bmp, options)) {
// inBitmap only works with mutable bitmaps, so force the decoder to
// return mutable bitmaps.
options.inMutable = true
options.inBitmap = bmp
}
options.inTempStorage = ByteArray(16 * 1024)
try {
bmp = BitmapFactory.decodeFile(imageFile.absolutePath, options)
} catch (exception: OutOfMemoryError) {
exception.printStackTrace()
}
var scaledBitmap: Bitmap? = null
try {
scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888)
} catch (exception: OutOfMemoryError) {
exception.printStackTrace()
}
val ratioX = actualWidth / options.outWidth.toFloat()
val ratioY = actualHeight / options.outHeight.toFloat()
val middleX = actualWidth / 2.0f
val middleY = actualHeight / 2.0f
val scaleMatrix = Matrix()
scaleMatrix.setScale(ratioX, ratioY, middleX, middleY)
val canvas = Canvas(scaledBitmap!!)
canvas.setMatrix(scaleMatrix)
canvas.drawBitmap(
bmp!!, middleX - bmp.width / 2,
middleY - bmp.height / 2, Paint(Paint.FILTER_BITMAP_FLAG)
)
bmp.recycle()
val exif: ExifInterface
try {
exif = ExifInterface(imageFile.absolutePath)
val orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0)
val matrix = Matrix()
if (orientation == 6) {
matrix.postRotate(90f)
} else if (orientation == 3) {
matrix.postRotate(180f)
} else if (orientation == 8) {
matrix.postRotate(270f)
}
scaledBitmap = Bitmap.createBitmap(
scaledBitmap, 0, 0, scaledBitmap.width,
scaledBitmap.height, matrix, true
)
} catch (e: IOException) {
e.printStackTrace()
}
return scaledBitmap
}
private fun calculateInSampleSize(
options: BitmapFactory.Options,
reqWidth: Int,
reqHeight: Int
): Int {
// Raw height and width of image
val height = options.outHeight
val width = options.outWidth
var inSampleSize = 1
if (height > reqHeight || width > reqWidth) {
inSampleSize *= 2
val halfHeight = height / 2
val halfWidth = width / 2
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while (halfHeight / inSampleSize >= reqHeight && halfWidth / inSampleSize >= reqWidth) {
inSampleSize *= 2
}
}
return inSampleSize
}
/**
* Ref: https://developer.android.com/topic/performance/graphics/manage-memory#kotlin
*/
private fun canUseForInBitmap(candidate: Bitmap, targetOptions: BitmapFactory.Options): Boolean {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// From Android 4.4 (KitKat) onward we can re-use if the byte size of
// the new bitmap is smaller than the reusable bitmap candidate
// allocation byte count.
val width: Int = targetOptions.outWidth / targetOptions.inSampleSize
val height: Int = targetOptions.outHeight / targetOptions.inSampleSize
val byteCount: Int = width * height * getBytesPerPixel(candidate.config)
byteCount <= candidate.allocationByteCount
} else {
// On earlier versions, the dimensions must match exactly and the inSampleSize must be 1
candidate.width == targetOptions.outWidth &&
candidate.height == targetOptions.outHeight &&
targetOptions.inSampleSize == 1
}
}
/**
* A helper function to return the byte usage per pixel of a bitmap based on its configuration.
*/
private fun getBytesPerPixel(config: Bitmap.Config): Int {
return when (config) {
Bitmap.Config.ARGB_8888 -> 4
Bitmap.Config.RGB_565, Bitmap.Config.ARGB_4444 -> 2
Bitmap.Config.ALPHA_8 -> 1
else -> 1
}
}
#Throws(IOException::class)
fun Context.createImageFile(): File {
// Create an image file name
val storageDir: File? = getExternalFilesDir(Environment.DIRECTORY_PICTURES)
return File.createTempFile(
"JPEG_${System.currentTimeMillis()}_", /* prefix */
".jpg", /* suffix */
storageDir /* directory */
)
}
and simply call the following method to create compressed image file. here file is you image file
file.compressImage(
1024f,
1024f,
Bitmap.CompressFormat.JPEG,
70,
context.createImageFile().path
)

Loading Bitmaps efficiently - still getting out of memory error

I was getting out of memory errors loading custom images. I read https://developer.android.com/training/displaying-bitmaps/load-bitmap.html for assistance.
I'm following the example to decode the stream to get size information first, then decode. Still crashing on that first decoding. Is there a way around this?
ava.lang.OutOfMemoryError: Failed to allocate a 48771084 byte allocation with 16776928 free bytes and 25MB until OOM
BackgroundImageManager.java, line 84
dalvik.system.VMRuntime.newNonMovableArray Native Method
2 android.graphics.BitmapFactory.nativeDecodeStream Native Method
3 android.graphics.BitmapFactory.decodeStreamInternal BitmapFactory.java, line 882
4 android.graphics.BitmapFactory.decodeStream BitmapFactory.java, line 858
5 android.graphics.BitmapFactory.decodeStream BitmapFactory.java, line 896
6 com.myapp.Utils.BackgroundImageManager.background BackgroundImageManager.java, line 8
public class BackgroundImageManager {
private final static String TAG = BackgroundImageManager.class.getSimpleName();
private static InputStream currentBackgroundImage;
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
Log.v("Biscuit-Sample", String.valueOf(inSampleSize));
if (inSampleSize < 4) {
inSampleSize = 4;
}
return inSampleSize;
}
public static Drawable background(Context context, Store store) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
String bgUri = null;
int bgId = 0;
if (store != null) {
bgUri = store.backgroundImageURI;
bgId = store.backgroundImageNumber;
}
if (currentBackgroundImage != null) {
try {
currentBackgroundImage.close();
Log.v(TAG, "Current background image closed.");
} catch (IOException e) {
Log.e(TAG, "Could not close background image.", e);
}
}
if(bgUri != null && !bgUri.isEmpty()) {
try {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Activity activity = (Activity) context;
Display display = activity.getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
BitmapFactory.decodeStream( context.getContentResolver().openInputStream(Uri.parse(bgUri)) );
options.inSampleSize = BackgroundImageManager.calculateInSampleSize(options, width, height);
Bitmap bitmap = BitmapFactory.decodeStream( context.getContentResolver().openInputStream(Uri.parse(bgUri)) );
Drawable d = new BitmapDrawable(context.getResources(), bitmap);
return d;
} catch (FileNotFoundException e) {
Log.e(TAG, "Custom background image file could not be found.", e);
} catch (IOException e) {
Log.e(TAG, "Could not close custom background image after creating drawable", e);
}
}
if(bgId != 0) {
try {
return context.getResources().getDrawable(bgId);
} catch (Exception e) {
e.printStackTrace();
}
}
return context.getResources().getDrawable(R.drawable.bg_default);
}
To handle bitmpas you can use one of the many opensource libraries available. E.g Fresco
to your issue:
First you are decoding the same bitmap twice.
BitmapFactory.decodeStream( context.getContentResolver().openInputStream(Uri.parse(bgUri)) );
options.inSampleSize = BackgroundImageManager.calculateInSampleSize(options, width, height);
Bitmap bitmap = BitmapFactory.decodeStream( context.getContentResolver().openInputStream(Uri.parse(bgUri)) );
It is probably a wrong copy/paste. In the first line the bitmap is decode and not used. Delete the first BitmapFactory.decodeStream
the problem lies here
Bitmap bitmap = BitmapFactory.decodeStream( context.getContentResolver().openInputStream(Uri.parse(bgUri)) );
it should be
Bitmap bitmap = BitmapFactory.decodeStream( context.getContentResolver().openInputStream(Uri.parse(bgUri)), null, options);
the option's object has to be part of the method's call in order to be used.
Better way to manage images is with the Picasso library because it manages cache and ram, and therefore avoiding OutOfMemory crash.
Example: Picasso.with(Context).load("your_url").into(yourImageView);
More info here:
Picasso library

Save Mat (openCV) to SharedPreferences Android

I'm writting app, which using KNearest. I wrote code to train model, but every restart app, I must train data again, so I would like to save train data to SharedPreferences once and using it after.
I know that I must convert Mat to byte[] and then to String, but decode is not working, I got error:
(layout == ROW_SAMPLE && responses.rows == nsamples)
|| (layout == COL_SAMPLE && responses.cols == nsamples)
in function void cv::ml::TrainDataImpl::setData(cv::InputArray,
int, cv::InputArray, cv::InputArray,
cv::InputArray, cv::InputArray, cv::InputArray, cv::InputArray)
Code:
protected Void doInBackground(Void... args) {
// Constants.TRAIN_SAMPLES = 10
Mat trainData = new Mat(0, 200 * 200, CvType.CV_32FC1); // 0 x 40 000
Mat trainClasses = new Mat(Constants.TRAIN_SAMPLES, 1, CvType.CV_32FC1); // 10 x 1
float[] myint = new float[Constants.TRAIN_SAMPLES + 1];
for (i = 1; i <= Constants.TRAIN_SAMPLES; i++)
myint[i] = (float) i;
trainClasses.put(0, 0, myint);
KNearest knn = KNearest.create();
String val = " ";
val = sharedPref.getString("key", " ");
// empty SharedPreferences
if (val.equals(" ")) {
// get all images from external storage
for (i = 1; i <= Constants.TRAIN_SAMPLES; i++) {
String photoPath = Environment.getExternalStorageDirectory().toString() + "/ramki/ramka_" + i + ".png";
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeFile(photoPath, options);
Utils.bitmapToMat(bitmap, img);
if (img.channels() == 3) {
Imgproc.cvtColor(img, img, Imgproc.COLOR_RGB2GRAY);
} else if (img.channels() == 4) {
Imgproc.cvtColor(img, img, Imgproc.COLOR_RGBA2GRAY);
}
Imgproc.resize(img, img, new Size(200, 200));
img.convertTo(img, CvType.CV_32FC1);
img = img.reshape(1, 1); // 1 x 40 000 ( 200x200 )
trainData.push_back(img);
publishProgress(i);
}
trainData.convertTo(trainData, CvType.CV_8U);
// save this trainData (Mat) to SharedPreferences
saveMatToPref(trainData);
} else {
// get trainData from SharedPreferences
val = sharedPref.getString("key", " ");
byte[] data = Base64.decode(val, Base64.DEFAULT);
trainData.convertTo(trainData, CvType.CV_8U);
trainData.put(0, 0, data);
}
trainData.convertTo(trainData, CvType.CV_32FC1);
knn.train(trainData, Ml.ROW_SAMPLE, trainClasses);
trainClasses.release();
trainData.release();
img.release();
onPostExecute();
return null;
}
public void saveMatToPref(Mat mat) {
if (mat.isContinuous()) {
int cols = mat.cols();
int rows = mat.rows();
byte[] data = new byte[cols * rows];
// there, data contains {0,0,0,0,0,0 ..... } 400 000 items
mat.get(0, 0, data);
String dataString = new String(Base64.encode(data, Base64.DEFAULT));
SharedPreferences.Editor mEdit1 = sharedPref.edit();
mEdit1.putString("key", dataString);
mEdit1.commit();
} else {
Log.i(TAG, "Mat not continuous.");
}
}
When I decode, my trainData look like this:
Mat [ 0*40000*CV_32FC1 ..]
but should: Mat [ 10*40000*CV_32FC1 ..]
Can anybody help me to encode and decode Mat? Thx for help.
As #Miki mention, problem was in types. Now it works, but only with Mat size around 200 x 40 000 in my case, if it's bigger, I have outOfMemory excepion...
String val = " ";
val = sharedPref.getString("key", " ");
// empty SharedPreferences
if ( ! val.equals(" ")) {
// get all images from external storage
for (i = 1; i <= Constants.TRAIN_SAMPLES; i++) {
String photoPath = Environment.getExternalStorageDirectory().toString() + "/ramki/ramka_" + i + ".png";
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeFile(photoPath, options);
Utils.bitmapToMat(bitmap, img);
if (img.channels() == 3) {
Imgproc.cvtColor(img, img, Imgproc.COLOR_RGB2GRAY);
} else if (img.channels() == 4) {
Imgproc.cvtColor(img, img, Imgproc.COLOR_RGBA2GRAY);
}
Imgproc.resize(img, img, new Size(200, 200));
img.convertTo(img, CvType.CV_32FC1);
img = img.reshape(1, 1); // 1 x 40 000 ( 200x200 )
trainData.push_back(img);
publishProgress(i);
}
// save this trainData (Mat) to SharedPreferences
saveMatToPref(trainData);
} else {
// get trainData from SharedPreferences
val = sharedPref.getString("key", " ");
byte[] data = Base64.decode(val, Base64.DEFAULT);
trainData = new Mat(Constants.TRAIN_SAMPLES, 200 * 200, CvType.CV_32FC1);
float[] f = toFloatArray(data);
trainData.put(0, 0, f);
}
knn.train(trainData, Ml.ROW_SAMPLE, trainClasses);
public void saveMatToPref(Mat mat) {
if (mat.isContinuous()) {
int size = (int)( mat.total() * mat.channels() );
float[] data = new float[ size ];
byte[] b = new byte[ size ];
mat.get(0, 0, data);
b = FloatArray2ByteArray(data);
String dataString = new String(Base64.encode(b, Base64.DEFAULT));
SharedPreferences.Editor mEdit1 = sharedPref.edit();
mEdit1.putString("key", dataString);
mEdit1.commit();
} else {
Log.i(TAG, "Mat not continuous.");
}
}
private static float[] toFloatArray(byte[] bytes) {
ByteBuffer buffer = ByteBuffer.wrap(bytes);
FloatBuffer fb = buffer.asFloatBuffer();
float[] floatArray = new float[fb.limit()];
fb.get(floatArray);
return floatArray;
}
public static byte[] FloatArray2ByteArray(float[] values){
ByteBuffer buffer = ByteBuffer.allocate(4 * values.length);
for (float value : values)
buffer.putFloat(value);
return buffer.array();
}
If someone have better solution, please add.

BitmapFactory Not working in Android

This line of code always returns null after cropping:
this.bmp = BitmapFactory.decodeFile(this.imageFileUri.getPath());
This is my crop method:
private void performCrop() {
this.imageFileUri = Uri.fromFile(this.file);
Intent var1 = new Intent("com.android.camera.action.CROP");
var1.setDataAndType(this.imageFileUri, "image/*");
System.out.println(this.imageFileUri.getPath());
var1.putExtra("crop", "true");
var1.putExtra("scale", true);
var1.putExtra("return-data", true);
// var1.putExtra("output", this.imageFileUri);
intent.putExtra(MediaStore.EXTRA_OUTPUT, this.imageFileUri);
this.startActivityForResult(var1, 1);
}
I have tried by using a custom method to return the Bitmap it still returns null. This is the method
public static Bitmap decodeFile(String path) {
int orientation;
try {
if (path == null) {
return null;
}
// decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
// Find the correct scale value. It should be the power of 2.
final int REQUIRED_SIZE = 70;
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
Bitmap bm = BitmapFactory.decodeFile(path, o2);
Bitmap bitmap = bm;
ExifInterface exif = new ExifInterface(path);
orientation = exif
.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
Log.e("ExifInteface .........", "rotation =" + orientation);
// exif.setAttribute(ExifInterface.ORIENTATION_ROTATE_90, 90);
Log.e("orientation", "" + orientation);
Matrix m = new Matrix();
if ((orientation == ExifInterface.ORIENTATION_ROTATE_180)) {
m.postRotate(180);
// m.postScale((float) bm.getWidth(), (float) bm.getHeight());
// if(m.preRotate(90)){
Log.e("in orientation", "" + orientation);
bitmap = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(),
bm.getHeight(), m, true);
return bitmap;
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
m.postRotate(90);
Log.e("in orientation", "" + orientation);
bitmap = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(),
bm.getHeight(), m, true);
return bitmap;
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
m.postRotate(270);
Log.e("in orientation", "" + orientation);
bitmap = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(),
bm.getHeight(), m, true);
return bitmap;
}
return bitmap;
} catch (Exception e) {
return null;
}
}
And calling the above method this way:
this.bmp = MyClass.decodeFile(this.imageFileUri.getPath());
Kindly assist!

Why is the Bitmap object returning a value in one call and null in another?

I have a Bitmap object that displays perfectly fine when called by ImageView imgView's setImageBitmap() method, but when I call it through method steg() ..which has a Bitmap argument and uses said argument to pass through another method. The same Bitmap object is accessed in the method for its getWidth() value, but this time it returns null as explained by a NullPointerException in my LogCat. However, I don't understand how this could be so if it has a value for the setImageBitmap() method.
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
// Get the cursor
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
// Move to first row
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
imgDecodableString = cursor.getString(columnIndex);
cursor.close();
opt = new BitmapFactory.Options();
opt.inDither = false;
opt.inScaled = false;
opt.inDensity = 0;
opt.inJustDecodeBounds = false;
opt.inPurgeable = false;
opt.inSampleSize = 1;
opt.inScreenDensity = 0;
opt.inTargetDensity = 0;
Bitmap covBitmap = BitmapFactory.decodeFile(imgDecodableString, opt);
// Set the Image in ImageView after decoding the String
imgView.setImageBitmap(covBitmap);//Returns the pic fine`
But, when I pass the same Bitmap object (through a class and a method) to another method which contains the line below, my LogCat states that the object is null at the following line but it can't be null if it returned a value in the above setImageBitmap(). Btw, bm is the same Bitmap object renamed when passed to the new class.
bm.getWidth();//LogCat says this line can't run bc it there is a null object.
The Bitmap object gets passed cleanly through both methods and between the classes.
public Uri encode(Bitmap covering, String msg, Context context, String title) {
//the Bitmap argument is fine
final Runnable mIncrementProgress = new Runnable() {
public void run() {
System.out.println("mIncrement Runnable HERE");
}
};
final Handler handler = new Handler();
Uri result=null;
String s = msg;//String to be encoded
int width = covering.getWidth();//If this line gets deleted of course
int height = covering.getHeight();//this line throws the same error
int[] oneD = new int[width * height];
covering.getPixels(oneD, 0, width, 0, 0, width, height);
int density = covering.getDensity();
covering.recycle();
byte[] byteImage = LSB2bit.encodeMessage(oneD, width, height, s,
new ProgressHandler() {
private int mysize;
private int actualSize;`
These line snippets show how the object is passed.
String filePath = new Cover().imgDecodableString;
BitmapFactory.Options bmfo = new Cover().opt;
//all items below are in onCreate() method except more method steg()
bmfo = new BitmapFactory.Options();
bmfo.inDither = false;
bmfo.inScaled = false;
bmfo.inDensity = 0;
bmfo.inJustDecodeBounds = false;
bmfo.inPurgeable = false;
bmfo.inSampleSize = 1;
bmfo.inScreenDensity = 0;
bmfo.inTargetDensity = 0;
Bitmap bm = BitmapFactory.decodeFile(filePath, bmfo);
steg(bm);
public void steg(Bitmap cover) {//this method is not in the onCreate() of course
encode.encode(cover, "MESSAGE", context, title);
}
Thank you in advance to you all!

Categories