Here is what i want supposed to be : load floorplan in IndoorAtlas and show current location.
Here is my code :
public void loadFloorPlanImage(FloorPlan floorPlan) {
BitmapFactory.Options options = createBitmapOptions(floorPlan);
FutureResult<Bitmap> result = mIndoorAtlas.fetchFloorPlanImage(floorPlan,options);
result.setCallback(new ResultCallback<Bitmap>() {
#Override
public void onResult(final Bitmap result) {
runOnUiThread(new Runnable() {
#Override
public void run() {
ImageView imageView = (ImageView) findViewById(R.id.imageView);
imageView.setImageBitmap(result);
}
});
}
});
}
And this :
private BitmapFactory.Options createBitmapOptions(FloorPlan floorPlan) {
int reqWidth = 2048;
int reqHeight = 2048;
final int width = (int) floorPlan.dimensions[0];
final int height = (int) floorPlan.dimensions[1];
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
options.inSampleSize = inSampleSize;
return options;
}
I received error result :
java.lang.NullPointerException: Attempt to write to field 'int android.graphics.BitmapFactory$Options.inSampleSize' on a null object reference
at skripsi.ubm.studenttracking.indoor.createBitmapOptions(indoor.java:370)
at skripsi.ubm.studenttracking.indoor.loadFloorPlanImage(indoor.java:322)
at skripsi.ubm.studenttracking.indoor$1.onResult(indoor.java:163)
at skripsi.ubm.studenttracking.indoor$1.onResult(indoor.java:159)
Could you help me ?
You need to initialize like this:
BitmapFactory.Options options = new BitmapFactory.Options();
options = createBitmapOptions(floorPlan);
Related
Below is the code I use to read my image file when I save my image file using FileProvider:
public static Bitmap readBitmapFromIntentReturn(Context context, Intent intentReturn, Uri uri) {
try {
AssetFileDescriptor fileDescriptor = null;
fileDescriptor = context.getContentResolver().openAssetFileDescriptor(uri, "r");
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFileDescriptor(fileDescriptor.getFileDescriptor(), null, options);
options.inSampleSize = SystemFunctions.calculateInSampleSize(options);
options.inJustDecodeBounds = false;
Bitmap bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor.getFileDescriptor(), null, options);
return bitmap;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
2. Method use to resize the image before I upload it or other, not sure the size is resize correctly or not:
public static int calculateInSampleSize(BitmapFactory.Options options) {
final int reqHeight = 360;
final int reqWidth = 360;
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;
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
Log.d("TestSampleSize", "TestSampleSize : " + String.valueOf(inSampleSize));
return inSampleSize;
}
So i saw this xamarin document about loading large bitmaps efficiently. Yet im struggling to implement it for the gridview.
https://developer.xamarin.com/recipes/android/resources/general/load_large_bitmaps_efficiently/
So how can we implement it for a gridview's adapter?
Thank you in the advance.
So how can we implement it for a gridview's adapter?
You can create a class(ThumbImageFactory below) to wrap all the functions mentioned in the document:
public class ThumbImageFactory
{
public readonly Context context;
public ThumbImageFactory(Context c)
{
context = c;
}
public static int CalculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight)
{
// Raw height and width of image
float height = options.OutHeight;
float width = options.OutWidth;
double inSampleSize = 1D;
if (height > reqHeight || width > reqWidth)
{
int halfHeight = (int)(height / 2);
int halfWidth = (int)(width / 2);
// Calculate a inSampleSize that is a power of 2 - the decoder will use a value that is a power of two anyway.
while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth)
{
inSampleSize *= 2;
}
}
return (int)inSampleSize;
}
public Bitmap LoadScaledDownBitmapForDisplay(Resources res, BitmapFactory.Options options, int reqWidth, int reqHeight,int resourceId)
{
// Calculate inSampleSize
options.InSampleSize = CalculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.InJustDecodeBounds = false;
return BitmapFactory.DecodeResource(res, resourceId, options);
}
public BitmapFactory.Options GetBitmapOptionsOfImage(int resourceId)
{
BitmapFactory.Options options = new BitmapFactory.Options
{
InJustDecodeBounds = true
};
// The result will be null because InJustDecodeBounds == true.
Bitmap result = BitmapFactory.DecodeResource(context.Resources, resourceId, options);
int imageHeight = options.OutHeight;
int imageWidth = options.OutWidth;
return options;
}
}
Create an ThumbImageFactory instance in your Adapter and call the functions in GetView:
public class ImageAdapter : BaseAdapter
{
private readonly Context context;
private ThumbImageFactory thumbFactory;
public ImageAdapter(Context c)
{
context = c;
thumbFactory = new ThumbImageFactory(c);
}
...
public override View GetView(int position, View convertView, ViewGroup parent)
{
ImageView imageView;
if (convertView == null)
{
imageView = new ImageView(this.context);
imageView.LayoutParameters = new AbsListView.LayoutParams(150, 150);
imageView.SetScaleType(ImageView.ScaleType.CenterCrop);
imageView.SetPadding(0, 0, 0, 0);
}
else
{
imageView = (ImageView)convertView;
}
Bitmap bitmap = GetThumbImage(thumbIds[position]);
imageView.SetImageBitmap(bitmap);
return imageView;
}
public Bitmap GetThumbImage(int resourceId)
{
BitmapFactory.Options options = thumbFactory.GetBitmapOptionsOfImage(resourceId);
Bitmap bitmap=thumbFactory.LoadScaledDownBitmapForDisplay(context.Resources, options, 150, 150, resourceId);
return bitmap;
}
}
Notes: we can't modify the GetView to async, so I changed all the functions in document to sync functions. Here is is complete Demo.
I'm trying to find out for ages now why i got this memory leak in the viewholder of my listview.
The strange part is that when setting the imageview (coverIv) with ((BitmapDrawable)_activity.Resources.GetDrawable(Resource.Drawable.splash)).Bitmap, there's no problem at all.
When i use await ImageLoader.DecodeSampledBitmapFromResourceAsync (localImageLocation, imgWidth, imgHeight) ,there's a huge memory leak each time i scroll a bit in the listview
I tried finding the references with the memory analyzer tool but there were none... Although MAT says that the problem are the bitmaps
public void ImageLoaded(string localImageLocation)
{
int screenWidth = _activity.Resources.DisplayMetrics.WidthPixels;
int imgWidth = screenWidth - (int)ConvertDpToPix (32f);
int imgHeight = (int)(ConvertDpToPix(206f));
BundleProgress.Visibility = ViewStates.Gone;
if (CoverIv.Drawable != null)
{
((BitmapDrawable)CoverIv.Drawable).Bitmap.Recycle ();
((BitmapDrawable)CoverIv.Drawable).Bitmap.Dispose ();
CoverIv.SetImageDrawable (null);
}
CoverIv.SetImageBitmap
(
//MEMORYLEAK: await ImageLoader.DecodeSampledBitmapFromResourceAsync (localImageLocation, imgWidth, imgHeight)
((BitmapDrawable)_activity.Resources.GetDrawable(Resource.Drawable.splash)).Bitmap
);
The methods in the ImageLoader class:
public static async Task<Bitmap> DecodeSampledBitmapFromResourceAsync (String path,int reqWidth, int reqHeight)
{
// First decode with inJustDecodeBounds=true to check dimensions of the image
BitmapFactory.Options options = new BitmapFactory.Options();
options.InJustDecodeBounds = true;
Bitmap bitmap = await BitmapFactory.DecodeFileAsync(path, options);
// Calculate inSampleSize
options.InSampleSize = CalculateInSampleSize(options, reqWidth,
reqHeight);
// Decode bitmap with inSampleSize set
options.InJustDecodeBounds = false;
options.InPreferredConfig = Bitmap.Config.Argb8888;
//options.InDither = true;
return await BitmapFactory.DecodeFileAsync(path, options);
}
public static int CalculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight)
{
// Raw height and width of image
float height = options.OutHeight;
float width = options.OutWidth;
double inSampleSize = 1D;
if (height > reqHeight || width > reqWidth)
{
int halfHeight = (int)(height / 2);
int halfWidth = (int)(width / 2);
// Calculate a inSampleSize that is a power of 2 - the decoder will use a value that is a power of two anyway.
while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth)
{
inSampleSize *= 2;
}
}
return (int)inSampleSize;
}
The adapter:
public override View GetView (int position, View convertView, ViewGroup parent)
{
BaseBundelVO bundle = _bundles [position];
DSBundleListItem bundleHolder = null;
DSBundleArchiveItem archiveHolder = null;
int type = GetItemViewType(position);
if (convertView == null)
{
bundleHolder = new DSBundleListItem (_activity.ApplicationContext);
archiveHolder = new DSBundleArchiveItem (_activity.ApplicationContext);
switch (type)
{
case 0:
convertView = _activity.LayoutInflater.Inflate (Resource.Layout.dsBundleListItem, null);
bundleHolder.IconIv = convertView.FindViewById<ImageView> (Resource.Id.iconIv);
bundleHolder.CoverIv = convertView.FindViewById<ImageView> (Resource.Id.coverIv);
bundleHolder.CoverTitleTv = convertView.FindViewById<TextView> (Resource.Id.coverTitleTv);
bundleHolder.CoverSubTitleTv = convertView.FindViewById<TextView> (Resource.Id.coverSubTitleTv);
bundleHolder.BundleProgress = convertView.FindViewById<ProgressBar> (Resource.Id.bundleProgress);
convertView.Tag = bundleHolder;
break;
case 1:
convertView = _activity.LayoutInflater.Inflate (Resource.Layout.dsBundleArchiveItem, null);
archiveHolder.ArchiveTitleTv = convertView.FindViewById<TextView> (Resource.Id.archiveTitleTv);
archiveHolder.ArchiveSubTitleTv = convertView.FindViewById<TextView> (Resource.Id.archiveSubTitleTv);
convertView.Tag = archiveHolder;
break;
}
}
else
{
switch (type)
{
case 0:
bundleHolder = (DSBundleListItem)convertView.Tag;
break;
case 1:
archiveHolder = (DSBundleArchiveItem)convertView.Tag;
break;
}
}
switch (type)
{
case 0:
bundleHolder.CoverTitleTv.Text = bundle.Title;
bundleHolder.CoverSubTitleTv.Text = bundle.SubTitle;
bundleHolder.CoverIv.SetImageDrawable (null);
bundleHolder.IconIv.SetImageDrawable (null);
bundleHolder.LoadImage(bundle.CoverImageLocation,bundle.Icon);
break;
case 1:
archiveHolder.ArchiveTitleTv.Text = "Archief";
archiveHolder.ArchiveSubTitleTv.Text = "Bekijk onze eerder verschenen publicaties";
break;
}
return convertView;
}
public void SetData(List<BaseBundelVO> bundles)
{
_bundles.Clear ();
_bundles.AddRange(bundles);
}
Use the picasso library when using images, it works wonders!
I recommend Pisasso library too.
Here is the link: http://square.github.io/picasso/
It retrieve images from the web immediately and caching it locally.
You must simply add this line to your code after importing Picasso library:
Picasso.with(context).load("*your url*").into(*your image view*);
You can also load local images too!
Picasso.with(context).load("file:///android_asset/image.png").into(*your image view*);
Hope this will help,
Please try my code. I think that it is something wrong with your decoding:
private Bitmap DisplayRotatedPhoto(Uri path) {
String filePath = path.toString().substring(8);
Bitmap oriented = null;
BitmapFactory.Options bitmapFactoryOptions = new BitmapFactory.Options();
bitmapFactoryOptions.inJustDecodeBounds = true;
int REQUIRED_SIZE = 100;
int width_tmp = bitmapFactoryOptions.outWidth, height_tmp = bitmapFactoryOptions.outHeight;
int scale = 2;
while (true) {
if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale++;
}
BitmapFactory.Options bitmapFactoryOptions2 = new BitmapFactory.Options();
bitmapFactoryOptions2.inSampleSize = scale;
Bitmap bmp = BitmapFactory.decodeFile(filePath, bitmapFactoryOptions2);
}
I try a gallery app.
My app working 2 diffrent form.
From the Gallery or from camera selection,
if selected photos height large to width everything ok.
if Selected photos width large to height, photos seems vertical
Example,
This image width : 3264, height : 2448
My app in seems like this;
this is my decode size code, Sorry bad english, thank you.
private class DecodeSize extends AsyncTask<String,Void,Bitmap> {
private int reqWidth;
private int reqHeight;
private ImageView imageView;
private final WeakReference<ImageView> imageViewReference;
private DecodeSize(int reqWidth, int reqHeight, ImageView imageView) {
this.reqWidth = reqWidth;
this.reqHeight = reqHeight;
this.imageViewReference = new WeakReference<ImageView>(imageView);
}
public 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;
}
}
return inSampleSize;
}
#Override
protected Bitmap doInBackground(String... params) {
String photo_path = params[0];
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(photo_path, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(photo_path, options);
}
#Override
protected void onPostExecute(Bitmap bitmap) {
if(imageViewReference != null && bitmap !=null) {
final ImageView imageView = imageViewReference.get();
if (imageView != null) {
imageView.setImageBitmap(bitmap);
}
}
}
}
private void decodeSizeFunction(String picturePath) {
decodeSize = new DecodeSize(200,200,foto_image);
decodeSize.execute(picturePath);
}
I am displaying an image in full screen mode in samsung tab2,but whenever going to display large image then nothing display in the image view.
image_view.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/background_repet_"
android:orientation="vertical" >
<ImageView
android:id="#+id/imgFullImage"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:layout_margin="15dp"
/>
</LinearLayout>
FullImageActivity.java:-
ImageView imgFullImage;
String dispFilename;
String fileUrl;
Bitmap bitmap;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.image_view);
imgFullImage = (ImageView)findViewById(R.id.imgFullImage);
fileUrl = getIntent().getExtras().getString("fileurl");
dispFilename=getIntent().getExtras().getString("dispFilename");
imgFullImage.setScaleType(ScaleType.FIT_CENTER);
bitmap=decodeSampledBitmapFromResource(fileUrl,
getDeviceWidth(FullImageActivity.this),getDeviceHeight(FullImageActivity.this));
Log.e("Fill Image Size in
Bytes","====>"+bitmap.getByteCount());
Log.e("Bitmap width & height","===>"+bitmap.getWidth() +"x"+bitmap.getHeight());
imgFullImage.setImageBitmap(bitmap);
}
public static int getDeviceWidth(Activity activity) {
int deviceWidth = 0;
Point size = new Point();
WindowManager windowManager = activity.getWindowManager();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
windowManager.getDefaultDisplay().getSize(size);
deviceWidth = size.x;
} else {
Display display = windowManager.getDefaultDisplay();
deviceWidth = display.getWidth();
}
return deviceWidth;
}
#SuppressLint("NewApi")
public static int getDeviceHeight(Activity activity) {
int deviceHeight = 0;
Point size = new Point();
WindowManager windowManager = activity.getWindowManager();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
windowManager.getDefaultDisplay().getSize(size);
deviceHeight = size.y;
} else {
Display display = windowManager.getDefaultDisplay();
deviceHeight = display.getHeight();
}
return deviceHeight;
}
public static Bitmap decodeSampledBitmapFromResource(String pathName,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(pathName, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth,
reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(pathName, options);
}
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;
}
}
return inSampleSize;
}
Log:-
12-13 13:31:45.238: E/Fill Image Size in Bytes(24036): ====>15668224
12-13 13:31:45.238: E/Bitmap width & height(24036): ===>2288x1712
if any one have idea please reply.
Thanks in advance...
public static Bitmap decodeSampledBitmapFromResource(String pathName,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(pathName, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth,
reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(pathName, options);
}
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;
}
}
return inSampleSize;
}
Change to this :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#drawable/background_repet_" >
<ImageView android:id="#+id/imgFullImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_margin="15dp"
android:scaleType="fitCenter"/>
</LinearLayout>
#SuppressLint("NewApi")
public static int getDeviceWidth(Activity activity) {
int deviceWidth = 0;
Point size = new Point();
WindowManager windowManager = activity.getWindowManager();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
windowManager.getDefaultDisplay().getSize(size);
deviceWidth = size.x;
} else {
Display display = windowManager.getDefaultDisplay();
deviceWidth = display.getWidth();
}
return deviceWidth;
}
#SuppressLint("NewApi")
public static int getDeviceHeight(Activity activity) {
int deviceHeight = 0;
Point size = new Point();
WindowManager windowManager = activity.getWindowManager();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
windowManager.getDefaultDisplay().getSize(size);
deviceHeight = size.y;
} else {
Display display = windowManager.getDefaultDisplay();
deviceHeight = display.getHeight();
}
return deviceHeight;
}
you can use device height and width..and set this image in imageview..
ImageView image = new ImageView(viewHomeScreen);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.FILL_PARENT,
FrameLayout.LayoutParams.FILL_PARENT);
params.height = getDeviceHeight(activity);
params.width = getDevicewidth(activity);
FrameLayout framelayout = new FrameLayout(viewHomeScreen);
framelayout.addView(image, 0, params);
i hope this is useful to you
public static void setImagesNew(ImageView img, String pathName,
Activity activity) {
Bitmap bmp = decodeSampledBitmapFromResource(pathName,
getDeviceWidth(activity), getDeviceHeight(activity));
img.setImageBitmap(bmp);
bmp = null;
System.gc();
Runtime.getRuntime().gc();
}
use this function,imagesize will be compatible with your device height width..
your issue related to image ?
so this is best solution ....