image take space when i load image i don;t understand what is the problem why is take space after first iamge other image is display normallly u can see my activity java class which have imagedisplay method i am alos load image here in this image is take space before and after first image
myactivity.java
public void imagedisplay()
{
itable = (TableLayout)findViewById(R.id.itable);
String chekplace=null;
Log.e("MyList Size", "Counted--->"+mylist.size());
int size=mylist.size();
s:
for(int j=0;j<mylist.size();j++)
{
trstate = new TableRow(this);
trstate.setGravity(Gravity.CENTER_HORIZONTAL);
tstate = new TextView(this);
tstate.setGravity(Gravity.CENTER);
String tempstate = mylist.get(j).get(KEY_PLACENAME).intern().toString();
tstate.setText(tempstate);
trstate.addView(tstate);
itable.addView(trstate);
chekplacename=mylist.get(j).get(KEY_PLACENAME).intern().toString();
int counter=1;
String nextplace=chekplacename;
chekplace=nextplace;
m:
while(nextplace==chekplace)
{
trimage = new TableRow(this);
trimage.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
for (int m = 1; m <= 4; m++)
{
chekplace=mylist.get(j).get(KEY_PLACENAME).intern().toString();
if(nextplace==chekplace)
{
iimage = new ImageView(this);
iimage.setPadding(2,2,2,2);
BitmapFactory.Options bmOptions;
bmOptions = new BitmapFactory.Options();
bmOptions.inSampleSize = 4;
String loadimageurl=mylist.get(j).get(KEY_PHOTOURL).intern().toString();
counter++
bm = LoadImage(loadimageurl, bmOptions);
int height=bm.getWidth();
int width=bm.getHeight();
Log.e("newheight","Before--->" +height);
Log.e("new width","Before--->"+width);
bm=resize(bm, bm.getHeight(), bm.getWidth());
height=bm.getWidth();
width=bm.getHeight();
iimage.setLayoutParams(new TableRow.LayoutParams( height, width));
iimage.setImageBitmap(bm);
trimage.addView(iimage);
}
}
itable.addView(trimage);
}
}
Related
This question already has answers here:
equals vs Arrays.equals in Java
(9 answers)
Closed 5 years ago.
i'm doing a image puzzle game in android i successfully loaded image from gallery and splitted and shuffle the bitmap and made a puzzle gave now i want to check whether the puzzl;e played is finished on clicking a button first i tried like this,
public void checkresult(View view)
{
if(beforeshuffle.toArray().equals(aftershuffle.toArray()))
{
Toast.makeText(getApplicationContext(),"correct",Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(getApplicationContext(),"wrong",Toast.LENGTH_SHORT).show();
}
}
but id didn't work so please do say me a logic to do this.
My complete code
public class SmallImageActivity extends Activity {
ImageView img;
GridView image_grid;
Bitmap bs,as;
ArrayList<Bitmap> beforeshuffle = new ArrayList<Bitmap>(9);
ArrayList<Bitmap> aftershuffle = new ArrayList<Bitmap>(9);
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.child_image);
//Getting the image chunks sent from the previous activity
// ArrayList<Bitmap> smallImage = getIntent().getParcelableArrayListExtra("small images");
//Getting the grid view and setting an adapter to it
img = (ImageView) findViewById(R.id.image);
image_grid = (GridView) findViewById(R.id.gridview);
Intent intent = getIntent();
String pathinphone = intent.getExtras().getString("path");
Log.d("path", pathinphone);
loadImageFromStorage(pathinphone);
}
private void splitImage(ImageView image, int smallimage_Numbers) {
final ArrayList<Bitmap> smallimages = new ArrayList<Bitmap>(9);
//For the number of rows and columns of the grid to be displayed
int rows, cols;
//For height and width of the small image smallimage_s
int smallimage_Height, smallimage_Width;
//To store all the small image smallimage_s in bitmap format in this list
//Getting the scaled bitmap of the source image
BitmapDrawable mydrawable = (BitmapDrawable) image.getDrawable();
Bitmap bitmap = mydrawable.getBitmap();
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth(), bitmap.getHeight(), true);
rows = cols = (int) Math.sqrt(smallimage_Numbers);
smallimage_Height = bitmap.getHeight() / rows;
smallimage_Width = bitmap.getWidth() / cols;
//xCo and yCo are the pixel positions of the image smallimage_s
int yCo = 0;
for (int x = 0; x < rows; x++) {
int xCo = 0;
for (int y = 0; y < cols; y++) {
smallimages.add(Bitmap.createBitmap(scaledBitmap, xCo, yCo, smallimage_Width, smallimage_Height));
xCo += smallimage_Width;
}
yCo += smallimage_Height;
}
Array []in=new Array[9];
for(int i=0;i<smallimages.size();i++)
{
beforeshuffle.add(smallimages.get(i));
}
Collections.shuffle(smallimages);
image_grid.setAdapter(new SmallImageAdapter(this, smallimages));
image_grid.setNumColumns((int) Math.sqrt(smallimages.size()));
image_grid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
int counter=0;
int firstclick;
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
counter ++;
if(counter % 2 == 0){
firstclick = position;
Bitmap data1 = smallimages.get(position);
}
else {
for(int i=0;i<smallimages.size();i++)
{
Bitmap swapImage = smallimages.get(position);
smallimages.set(position, smallimages.get(firstclick));
smallimages.set(firstclick, swapImage);
image_grid.invalidateViews();
aftershuffle.add(smallimages.get(i));
}
}
}
});
}
public void checkresult(View view)
{
if(beforeshuffle.toArray().equals(aftershuffle.toArray()))
{
Toast.makeText(getApplicationContext(),"correct",Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(getApplicationContext(),"wrong",Toast.LENGTH_SHORT).show();
}
}
}
There is a method called sameAS in Bitmap class to compare,
You can try something below like this,
public void checkresult(View view)
{
if(beforeshuffle.size() > 0 && aftershuffle.size() > 0){
if(beforeshuffle.get(0).sameAs(aftershuffle.get(0)))
{
Toast.makeText(getApplicationContext(),"correct",Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(getApplicationContext(),"wrong",Toast.LENGTH_SHORT).show();
}
}
}
I hope this may help you,All the best
If your Min supported Version is 14 or above, then Bitmap class have a method
bitmap.sameAs()
which you can use here to compare bitmaps.
see the description
here
I think that if you remove toArray() it will do the job (comparing 2 arrays with equals is the same as doing array1 == array2 but comparing 2 lists with equals will compare their contents)
I'm making that find duplicate images.
I'm using this code for to do this
private static boolean compare(Bitmap b1, Bitmap b2) {
if (b1.getWidth() == b2.getWidth() && b1.getHeight() == b2.getHeight()) {
int[] pixels1 = new int[b1.getWidth() * b1.getHeight()];
int[] pixels2 = new int[b2.getWidth() * b2.getHeight()];
b1.getPixels(pixels1, 0, b1.getWidth(), 0, 0, b1.getWidth(), b1.getHeight());
b2.getPixels(pixels2, 0, b2.getWidth(), 0, 0, b2.getWidth(), b2.getHeight());
if (Arrays.equals(pixels1, pixels2)) {
return true;
} else {
return false;
}
} else {
return false;
}
}
The code works fine, but it's very slow when i put a List of Images.
public static Bitmap getBitmapFromPath(String path){
File sd = Environment.getExternalStorageDirectory();
File image = new File(path);
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inPreferredConfig = Bitmap.Config.RGB_565;
bmOptions.inSampleSize = 2;
Bitmap bitmap = BitmapFactory.decodeFile(image.getAbsolutePath(),bmOptions);
return bitmap;
}
public static ArrayList<String> compareListOfImages(Activity activity){
ArrayList<String> pathList = FileUtils.getImagesPath(activity);
ArrayList<String> pathListResult = new ArrayList<>();
if(pathList!=null) {
for (int i = 0; i < pathList.size(); i++){
Log.d("I", i + " ITEM");
Bitmap bitmap1 = FileUtils.getBitmapFromPath(pathList.get(i));
for (int k =0; k <pathList.size(); k++){
Log.d("PATH", pathList.get(k));
Bitmap bitmap2 = FileUtils.getBitmapFromPath(pathList.get(k));
if(!pathList.get(i).equals(pathList.get(k))) {
if (FileUtils.compare(bitmap1, bitmap2)) {
pathListResult.add(pathList.get(k));
}
}
}
}
}
return pathListResult;
}
Someone know a othe way to get result more fast?
My application is able to take pictures and to save and to show them in a list. They also can be deleted and the list is correctly updated.
However, if I close the application and then launch it again, the list is no more correct. In detail:
These are the list elements in the adapter after I take two pictures:
List[0] 20150603_042556
List[1] 20150603_042601
These pictures are correctly saved. However, if I close and open again the application, this is what happens:
Loaded selfie:﹕ 20150603_042556
List[0] 20150603_042556
Loaded selfie: 20150603_042601
List[0] 20150603_042601
List[1] 20150603_042601
This is the add function:
public void add(SelfieRecord listItem) {
list.add(listItem);
for(int k=0;k<list.size();k++)
Log.i("List: ", String.valueOf(k) + " " + list.get(k).getPicName());
notifyDataSetChanged();
}
This is how I load the saved pictures:
for (int ii = 0; ii < dirFiles.length; ii++) {
File file = dirFiles[ii];
String path = file.getAbsolutePath();
selfie.setPic(path);
selfie.setPicName(path.substring(path.indexOf("_") + 1, path.lastIndexOf("_")));
Log.i(TAG+" Loaded selfie: ",path);
mAdapter.add(selfie);
}
Can't figure out what happens.
EDIT: More code follows.
In the main activity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// setup notifications
setNotifications();
mListView = (ListView)findViewById(R.id.selfieList);
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(MainActivity.this, ViewActivity.class);
SelfieRecord record = (SelfieRecord) mAdapter.getItem(position);
intent.putExtra(SELFIE_KEY, record.getPic());
startActivity(intent);
}
});
mAdapter = new SelfieAdapter(getApplicationContext());
mListView.setAdapter(mAdapter);
// load selfies
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) && mAdapter.getCount()==0) {
// gets the files in the directory
File fileDirectory = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES).getAbsolutePath());
if (!fileDirectory.exists()) {
fileDirectory.mkdirs();
}
// lists all the files into an array
File[] dirFiles = fileDirectory.listFiles();
if (dirFiles.length != 0) {
SelfieRecord selfie = new SelfieRecord();
// loops through the array of files, outputing the name to console
for (int ii = 0; ii < dirFiles.length; ii++) {
File file = dirFiles[ii];
String path = file.getAbsolutePath();
selfie.setPic(path);
selfie.setPicName(path.substring(path.indexOf("_") + 1, path.lastIndexOf("_")));
Log.i(TAG+" Loaded selfie: ",path);
mAdapter.add(selfie);
}
}
}
registerForContextMenu(mListView);
}
In the Adapter:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View newView = convertView;
ViewHolder holder;
SelfieRecord curr = list.get(position);
Log.i("List: ", String.valueOf(position)+" "+list.get(position).getPicName());
if (null == convertView) {
holder = new ViewHolder();
newView = inflater.inflate(R.layout.list_record, parent, false);
holder.pic = (ImageView) newView.findViewById(R.id.pic);
holder.name = (TextView) newView.findViewById(R.id.pic_name);
newView.setTag(holder);
} else {
holder = (ViewHolder) newView.getTag();
}
//setPic(holder.pic, curr.getPic());
holder.name.setText(curr.getPicName());
mImageView = holder.pic;
new BitmapLoader().execute(curr.getPic());
Log.i("Loader: ", String.valueOf(position) + " " + curr.getPicName());
return newView;
}
static class ViewHolder {
ImageView pic;
TextView name;
}
public void add(SelfieRecord listItem) {
list.add(listItem);
for(int k=0;k<list.size();k++)
Log.i("List: ", String.valueOf(k) + " " + list.get(k).getPicName());
notifyDataSetChanged();
}
public void remove(int position) {
list.remove(position);
notifyDataSetChanged();
}
Bitmap Loader:
public class BitmapLoader extends AsyncTask<String,Integer,Bitmap> {
#Override
protected Bitmap doInBackground(String... resId) {
// Get the dimensions of the View
int targetW = Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 160, mContext.getResources().getDisplayMetrics()));
int targetH = Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 120, mContext.getResources().getDisplayMetrics()));
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(resId[0], bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(resId[0], bmOptions);
return bitmap;
}
#Override
protected void onPostExecute(Bitmap result) {
mImageView.setImageBitmap(result);
}
}
I believe the problem is when I put the elements in the adapter after recovered them from storage:
Loaded selfie:﹕ 20150603_042556
List[0] 20150603_042556
Loaded selfie: 20150603_042601
List[0] 20150603_042601
List[1] 20150603_042601
The second call to the adapter's add method overwrite the first element. Why?
Solved by changing the for loop in on Create:
if (dirFiles.length != 0) {
// loops through the array of files, outputing the name to console
for (int ii = 0; ii < dirFiles.length; ii++) {
File file = dirFiles[ii];
String path = file.getAbsolutePath();
SelfieRecord selfie = new SelfieRecord();
selfie.setPic(path);
selfie.setPicName(path.substring(path.indexOf("_") + 1, path.lastIndexOf("_")));
Log.i(TAG+" Loaded selfie: ",path);
mAdapter.add(selfie);
}
}
Must pass a different SelfieRecord Object to the add method.
In my app I am using a listview and a listadapter. When one clicks on a certain subitem in the listview there's a clickable textview that loads several bitmaps to a scrollview - and this scrollview is shown in an alertdialog.
All this happens in a class that extends BaseExpandableListAdapter and when this textlink is clicked - a static inner class is called that is responsible to load all these (9) bitmaps. This inner class extends asynctask.
Before these bitmaps are loaded to the scrollview - two static methods of this inner-class are called that scaleddown the bitamps to a size that fits the screen. Here I use Bitmapfactory.decoderesource and Bitmap.scaledownBitmap.
All this works FINE, .. BUT the program suffers from a memoryleak. This leak was rather big before because this inner class was non-static. So the leak was reduced by making this inner class static. Yes - reduced, but not eliminated.
I have also made weakreference of several objects but without success. For example - I made a weak reference of the object that refers to the inner-class. I have made a weak reference of the context that is passed to the innerclass. I have even made w weak reference of the bitmaps. No success at all.
The heapsize of my Samsung Galazy s3 is 64 MB. When the listview with all its subitem is first loaded used heap is about 17 MB. Then when 9 bitmaps are loaded it jumbs to about 42 MB. If I then click on another subitem with images used heap is the same - but after continue clicking and loading bitmaps the heap suddenly jumbs to 47 MB ... then the same scenario .... stands still for a while - then up to 52 MB .... 56 MB. So I have to click and load bitmaps pretty much to get out-of-memory. Let say 15 - 20 minutes of intensive use.
conclusion: To make the inner-class static helped me to reduce the memory leak. But despite making weakreferences of several objects (especially context) I have not been able to reduce leak further.
Any suggestions?
The code below is a bit messy ....
static class BitmapWorkerTask extends AsyncTask <Integer, Void, Bitmap[]> {
private int[] data;
private int[] width, height;
private int nmbrOfImages;
private String[] scrollText;
private ImageView mImage;
private View view;
private LayoutInflater factory;
private AlertDialog.Builder alertadd;
private Context context;
private WeakReference <Context> sc;
private WeakReference <ImageView> mImageV;
private WeakReference <Bitmap[]> bitmapV;
public BitmapWorkerTask(int[] width, int[] height, int nmbrOfImages, String[] scrollText, Context context) {
this.width = width;
this.height = height;
this.nmbrOfImages = nmbrOfImages;
this.scrollText = scrollText;
this.context = context;
mImage = null;
view = null;
factory = null;
alertadd = null;
System.gc();
sc = new WeakReference <Context> (context);
try {
for (int i = 0; i < scaledBitmap.length; i++) {
scaledBitmap[i].recycle();
scaledBitmap[i] = null;
}
} catch (NullPointerException ne) {
System.out.println("nullpointerexception ... gick inte recycla bitmapbilder");
}
switch (nmbrOfImages) {
case 0:
data = new int[1];
break;
case 1:
data = new int[3];
break;
case 2:
data = new int[5];
break;
case 3:
data = new int[9];
break;
}
}
#Override
protected Bitmap[] doInBackground(Integer ... params) {
switch (nmbrOfImages) {
case 0:
data[0] = params[0];
break;
case 1:
data[0] = params[0];
data[1] = params[1];
data[2] = params[2];
break;
case 2:
data[0] = params[0];
data[1] = params[1];
data[2] = params[2];
data[3] = params[3];
data[4] = params[4];
break;
case 3:
data[0] = params[0];
data[1] = params[1];
data[2] = params[2];
data[3] = params[3];
data[4] = params[4];
data[5] = params[5];
data[6] = params[6];
data[7] = params[7];
data[8] = params[8];
break;
}
alertadd = new AlertDialog.Builder(sc.get());
factory = LayoutInflater.from(sc.get());
Bitmap[] bm = decodeSampledBitmapFromResource(sc.get().getResources(), data, width, height);
bitmapV = new WeakReference <Bitmap[]> (bm);
return bitmapV.get();
}
protected void onPostExecute(Bitmap[] bitmap) {
switch (nmbrOfImages) {
case 0:
if (view == null) {
view = factory.inflate(R.layout.alertviews, null);
}
mImage = (ImageView) view.findViewById(R.id.extra_img);
mImage.setImageBitmap(bitmap[0]);
alertadd.setView(view);
alertadd.setNeutralButton("Here!", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dlg, int sumthin) {
}
});
alertadd.show();
break;
case 1:
if (view == null) {
view = factory.inflate(R.layout.alertviews2, null);
}
mImage = (ImageView) view.findViewById(R.id.img1);
mImage.setImageBitmap(bitmap[0]);
mImage = (ImageView) view.findViewById(R.id.img2);
mImage.setImageBitmap(bitmap[1]);
mImage = (ImageView) view.findViewById(R.id.img3);
mImage.setImageBitmap(bitmap[2]);
try {
TextView mText2 = (TextView) view.findViewById(R.id.text_img1_scrollview);
mText2.setText(scrollText[0]);
mText2 = (TextView) view.findViewById(R.id.text_img2_scrollview);
mText2.setText(scrollText[1]);
mText2 = (TextView) view.findViewById(R.id.text_img3_scrollview);
mText2.setText(scrollText[2]);
} catch (NullPointerException ne) {
System.out.println("nullpointerexception ... TextView i metoden onPostExecute");
}
alertadd.setView(view);
alertadd.setNeutralButton("Here!", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dlg, int sumthin) {
}
});
alertadd.show();
break;
case 2:
if (view == null) {
view = factory.inflate(R.layout.alertviews3, null);
}
mImage = (ImageView) view.findViewById(R.id.img1);
mImage.setImageBitmap(bitmap[0]);
mImage = (ImageView) view.findViewById(R.id.img2);
mImage.setImageBitmap(bitmap[1]);
mImage = (ImageView) view.findViewById(R.id.img3);
mImage.setImageBitmap(bitmap[2]);
mImage = (ImageView) view.findViewById(R.id.img4);
mImage.setImageBitmap(bitmap[3]);
mImage = (ImageView) view.findViewById(R.id.img5);
mImage.setImageBitmap(bitmap[4]);
try {
TextView mText3 = (TextView) view.findViewById(R.id.text_img1_scrollview);
mText3.setText(scrollText[0]);
mText3 = (TextView) view.findViewById(R.id.text_img2_scrollview);
mText3.setText(scrollText[1]);
mText3 = (TextView) view.findViewById(R.id.text_img3_scrollview);
mText3.setText(scrollText[2]);
mText3 = (TextView) view.findViewById(R.id.text_img4_scrollview);
mText3.setText(scrollText[3]);
mText3 = (TextView) view.findViewById(R.id.text_img5_scrollview);
mText3.setText(scrollText[4]);
} catch (NullPointerException ne) {
System.out.println("nullpointerexception ... TextView i metoden onPostExecute");
}
alertadd.setView(view);
alertadd.setNeutralButton("Here!", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dlg, int sumthin) {
}
});
alertadd.show();
break;
case 3:
if (view == null) {
view = factory.inflate(R.layout.alertviews4, null);
}
AlertDialog.Builder alertadd = new AlertDialog.Builder(context);
mImage = (ImageView) view.findViewById(R.id.img1);
mImage.setImageBitmap(bitmap[0]);
mImage = (ImageView) view.findViewById(R.id.img2);
mImage.setImageBitmap(bitmap[1]);
mImage = (ImageView) view.findViewById(R.id.img3);
mImage.setImageBitmap(bitmap[2]);
mImage = (ImageView) view.findViewById(R.id.img4);
mImage.setImageBitmap(bitmap[3]);
mImage = (ImageView) view.findViewById(R.id.img5);
mImage.setImageBitmap(bitmap[4]);
mImage = (ImageView) view.findViewById(R.id.img6);
mImage.setImageBitmap(bitmap[5]);
mImage = (ImageView) view.findViewById(R.id.img7);
mImage.setImageBitmap(bitmap[6]);
mImage = (ImageView) view.findViewById(R.id.img8);
mImage.setImageBitmap(bitmap[7]);
mImage = (ImageView) view.findViewById(R.id.img9);
mImage.setImageBitmap(bitmap[8]);
try {
TextView mText4 = (TextView) view.findViewById(R.id.text_img1_scrollview);
mText4.setText(scrollText[0]);
mText4 = (TextView) view.findViewById(R.id.text_img2_scrollview);
mText4.setText(scrollText[1]);
mText4 = (TextView) view.findViewById(R.id.text_img3_scrollview);
mText4.setText(scrollText[2]);
mText4 = (TextView) view.findViewById(R.id.text_img4_scrollview);
mText4.setText(scrollText[3]);
mText4 = (TextView) view.findViewById(R.id.text_img5_scrollview);
mText4.setText(scrollText[4]);
mText4 = (TextView) view.findViewById(R.id.text_img6_scrollview);
mText4.setText(scrollText[5]);
mText4 = (TextView) view.findViewById(R.id.text_img7_scrollview);
mText4.setText(scrollText[6]);
mText4 = (TextView) view.findViewById(R.id.text_img8_scrollview);
mText4.setText(scrollText[7]);
mText4 = (TextView) view.findViewById(R.id.text_img9_scrollview);
mText4.setText(scrollText[8]);
} catch (NullPointerException ne) {
System.out.println("nullpointerexception ... TextView i metoden onPostExecute");
}
alertadd.setView(view);
alertadd.setNeutralButton("Here!", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dlg, int sumthin) {
}
});
alertadd.show();
break;
}
}
/**
*
* #param options
* #param reqW
* #param reqH
* #return
*/
public static int calculateInSampleSize(BitmapFactory.Options options, int reqW, int reqH) {
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
int inSampleSize = 1;
if (imageHeight > reqH || imageWidth > reqW) {
int heightRatio = Math.round((float) imageHeight / (float) reqH);
int widthRatio = Math.round((float) imageWidth / (float) reqW);
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
System.out.println("i if-satsen!");
System.out.println("height-ratio: " + heightRatio + "\nwidth-ratio: " + widthRatio);
}
System.out.println("samplesize: " + inSampleSize);
inSampleSize = inSampleSize;
return inSampleSize;
}
#SuppressLint("NewApi")
/**
*
* #param res
* #param resId
* #param reqW
* #param reqH
* #return
*/
public static Bitmap[] decodeSampledBitmapFromResource(Resources res, int[] resId, int[] reqW, int[] reqH) {
scaledBitmap = new Bitmap[resId.length];
BitmapFactory.Options options;
for (int i = 0; i < resId.length; i++) {
options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap bm =BitmapFactory.decodeResource(res, resId[i], options);
System.out.println("ursprunglig bild: h = " + options.outHeight + " w = " + options.outWidth);
options.inSampleSize = calculateInSampleSize(options, reqW[i], reqH[i]);
while (options.outHeight < reqH[i] || options.outWidth < reqW[i]) {
options.inSampleSize--;
System.out.println("räknar nu ner insampleseize\ninSamleSize =" + options.inSampleSize);
}
options.inJustDecodeBounds = false;
bm = BitmapFactory.decodeResource(res, resId[i], options);
System.out.println("innan omskalning: h = " + options.outHeight + " w = " + options.outWidth);
System.out.println("antalet bytes: " + bm.getByteCount());
System.out.println("native free size: " + Debug.getNativeHeapFreeSize() );
scaledBitmap[i] = Bitmap.createScaledBitmap(bm, reqW[i], reqH[i], true);
bm.recycle();
bm = null;
}
System.gc();
WeakReference <Bitmap[] > sc = new WeakReference <Bitmap[]> (scaledBitmap);
return sc.get();
}
}
}
You are keeping dual reference to your bitmaps
once weak and once hard copy
your problem code is :
Bitmap[] bm = decodeSampledBitmapFromResource(sc.get().getResources(), data, width, height);
bitmapV = new WeakReference <Bitmap[]> (bm);
you are not getting rid of the contents of bm
and you are doing it more than once
scaledBitmap[i] = Bitmap.createScaledBitmap(bm, reqW[i], reqH[i], true);
bm.recycle();
bm = null;
}
System.gc();
WeakReference <Bitmap[] > sc = new WeakReference <Bitmap[]> (scaledBitmap);
You should do this:
ArrayList<WeakReference<Bitmap>>scaledBitmaps= new ArrayList<WeakReference<Bitmap>>();
scaledBitmaps.add(new WeakReference<Bitmap>(Bitmap.createScaledBitmap...));
and do not use Bitmap[] array
So I have a function for an android app that is supposed to take any number of pictures and display them 5 pics for each row, for some reason when it goes to the second row, it just repeats the pics for the first row, for example if I have 7 pics numbered 1-7 they will display:
12345
12
here is my function, thanks for any advice.
public void generateImageView(int number, String path){
//ImageView[] imageViewArray = new ImageView[number];
int ROW_ITEMS = 5; // 5 images per row
RelativeLayout rl = (RelativeLayout) findViewById(R.id.RelativeLayout1);
int limit = number;//limits the number of created imageViews to number
int rows = limit / ROW_ITEMS;//number of rows
int leftOver = limit % ROW_ITEMS; //see if we have incomplete rows
if (leftOver != 0){
rows += 1;
}
int id = 1000;
int belowId = R.id.send;
while (rows > 0){
int realItemsPerRow = ROW_ITEMS;
if (leftOver != 0 & rows == 1){
realItemsPerRow = Math.min(ROW_ITEMS, leftOver);
}
for (int i = 0; i < realItemsPerRow; i++){
Bitmap myBitmap = BitmapFactory.decodeFile(path + i + ".png");
ImageView imageViewArray = new ImageView(MainActivity.this);
imageViewArray.setId(id);
imageViewArray.setImageBitmap(myBitmap);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
imageViewArray.setPadding(10,10,0,0);
imageViewArray.setAdjustViewBounds(true);
imageViewArray.setMaxHeight(80);
imageViewArray.setMaxWidth(80);
if (i==0) {
lp.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
} else {
lp.addRule(RelativeLayout.RIGHT_OF, imageViewArray.getId() -1);
}
lp.addRule(RelativeLayout.BELOW, belowId);
imageViewArray.setLayoutParams(lp);
rl.addView(imageViewArray);
id++;
}
belowId = id - 1;
rows--;
It's because you're just pulling the same images for each position in the row:
Bitmap myBitmap = BitmapFactory.decodeFile(path + i + ".png");
Before while( rows > 0 ) add:
int j = 0;
Then change the above to:
Bitmap myBitmap = BitmapFactory.decodeFile(path + ( j * ROW_ITEMS + i ) + ".png");
and under rows--; add:
j++;