1

I am needing some help with resizing a bitmap before sending it to the wallpaper manager so that when the user sets it as their wallpaper, it fits reasonably, 100% would be preferred.

I am using wallpaper manager and am getting the image from an ImageView.

The issue I am having is the wallpaper is really zoomed in. Before, when I set the wallpaper straight from the drawable directory, it looked fine and you could see a lot more of the image, not 1/4 of it. I have changed my code up since then and have found a lot more of an effective way to get my images and set the wallpaper.

I have looked at This link here and am trying to figure out how to implement the answer that shows you how to resize the image before sending it to the wallpaper manager.

Any help would be appreciated, cheers.

Relative code to question:

        @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    final View v = inflater.inflate(R.layout.image_detail_fragment,
            container, false);


    int Measuredwidth = 0;
    int Measuredheight = 0;         

    WindowManager w = getActivity().getWindowManager();

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
        w.getDefaultDisplay().getSize(Size);
        Measuredwidth = Size.x;
    Measuredheight = Size.y;
    } else {
        Display d = w.getDefaultDisplay();
    Measuredwidth = d.getWidth();
    Measuredheight = d.getHeight();
    }




    mImageView = (RecyclingImageView) v.findViewById(R.id.imageView);
    mImageView.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {

            BitmapDrawable drawable = (BitmapDrawable) mImageView
                    .getDrawable();
            Bitmap bitmap = drawable.getBitmap();

            WallpaperManager myWallpaperManager = WallpaperManager
                    .getInstance(getActivity());

            try {

                myWallpaperManager.setBitmap(bitmap);
                ;
                Toast.makeText(getActivity(),
                        "Wallpaper Successfully Set!", Toast.LENGTH_LONG)
                        .show();
            } catch (IOException e) {
                Toast.makeText(getActivity(), "Error Setting Wallpaper",
                        Toast.LENGTH_LONG).show();
            }

        }

My whole class:

public class ImageDetailFragment extends Fragment {
private static final String IMAGE_DATA_EXTRA = "extra_image_data";
private static final Point Size = null;
private String mImageUrl;
private RecyclingImageView mImageView;
private ImageFetcher mImageFetcher;

public static ImageDetailFragment newInstance(String imageUrl) {
    final ImageDetailFragment f = new ImageDetailFragment();

    final Bundle args = new Bundle();
    args.putString(IMAGE_DATA_EXTRA, imageUrl);
    f.setArguments(args);

    return f;
}

public ImageDetailFragment() {
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mImageUrl = getArguments() != null ? getArguments().getString(
            IMAGE_DATA_EXTRA) : null;

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    final View v = inflater.inflate(R.layout.image_detail_fragment,
            container, false);


    int Measuredwidth = 0;
    int Measuredheight = 0;         

    WindowManager w = getActivity().getWindowManager();

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
        w.getDefaultDisplay().getSize(Size);
        Measuredwidth = Size.x;
    Measuredheight = Size.y;
    } else {
        Display d = w.getDefaultDisplay();
    Measuredwidth = d.getWidth();
    Measuredheight = d.getHeight();
    }




    mImageView = (RecyclingImageView) v.findViewById(R.id.imageView);
    mImageView.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {

            BitmapDrawable drawable = (BitmapDrawable) mImageView
                    .getDrawable();
            Bitmap bitmap = drawable.getBitmap();

            WallpaperManager myWallpaperManager = WallpaperManager
                    .getInstance(getActivity());

            try {

                myWallpaperManager.setBitmap(bitmap);
                ;
                Toast.makeText(getActivity(),
                        "Wallpaper Successfully Set!", Toast.LENGTH_LONG)
                        .show();
            } catch (IOException e) {
                Toast.makeText(getActivity(), "Error Setting Wallpaper",
                        Toast.LENGTH_LONG).show();
            }

        }

    });

    return v;
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    if (Batmanark.class.isInstance(getActivity())) {
        mImageFetcher = ((Batmanark) getActivity()).getImageFetcher();
        mImageFetcher.loadImage(mImageUrl, mImageView);
    }


}

@Override
public void onDestroy() {
    super.onDestroy();
    if (mImageView != null) {
        // Cancel any pending image work
        ImageWorker.cancelWork(mImageView);
        mImageView.setImageDrawable(null);
    }
}
}
Community
  • 1
  • 1
Jack
  • 2,043
  • 7
  • 40
  • 69

2 Answers2

3

if you want to fit the wallpaper with the divice screen, then you have to follow the steps bellow:

  1. get the height and width of the divice screen
  2. sample the bitmap image
  3. resize the bitmap
  4. before setting the bitmap as wallpaper, recycle the previous bitmap

code:

step 1:

int Measuredwidth = 0;
int Measuredheight = 0; 

Point size = new Point();
// if you are doing it from an activity
WindowManager w = getWindowManager();
// otherwise use this
WindowManager w = context.getWindowManager();

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
    w.getDefaultDisplay().getSize(size);
    Measuredwidth = size.x;
Measuredheight = size.y;
} else {
    Display d = w.getDefaultDisplay();
Measuredwidth = d.getWidth();
Measuredheight = d.getHeight();
}

step 2+3:

public Bitmap resizeBitmap(Resources res, int reqWidth, int reqHeight, 
                           InputStream inputStream, int fileLength) {
    Bitmap bitmap = null;
    InputStream in = null; 
    InputStream in2 = null;
    InputStream in3 = null;  

    try {
        in3 = inputStream;              

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ByteArrayOutputStream out2 = new ByteArrayOutputStream();

        copy(in3,out,fileLength);
        out2 = out;
        in2 = new ByteArrayInputStream(out.toByteArray());
        in = new ByteArrayInputStream(out2.toByteArray());

        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(in, null, options);

                    if(options.outHeight == -1 || options.outWidth == 1 || options.outMimeType == null){
            return null;
    }                           

        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

        options.inJustDecodeBounds = false; 

        bitmap = BitmapFactory.decodeStream(in2, null, options);

        if(bitmap != null){
            bitmap = Bitmap.createScaledBitmap(bitmap, reqWidth, reqHeight, false);                     
        }
        in.close();
        in2.close();
        in3.close();
    } catch (IOException e1) {          
        e1.printStackTrace();
    }
    return bitmap;   
}

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) {

        // Calculate ratios of height and width to requested height and width
        final int heightRatio = Math.round((float) height / (float) reqHeight);
        final int widthRatio = Math.round((float) width / (float) reqWidth);

        // Choose the smallest ratio as inSampleSize value, this will guarantee a final image
        // with both dimensions larger than or equal to the requested height and width.
        inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;

        // This offers some additional logic in case the image has a strange
        // aspect ratio. For example, a panorama may have a much larger
        // width than height. In these cases the total pixels might still
        // end up being too large to fit comfortably in memory, so we should
        // be more aggressive with sample down the image (=larger inSampleSize).

        final float totalPixels = width * height;

        // Anything more than 2x the requested pixels we'll sample down further
        final float totalReqPixelsCap = reqWidth * reqHeight * 2;

        while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
            inSampleSize++;
        }
    }
    return inSampleSize;
}

public int copy(InputStream input, OutputStream output, int fileLength) throws IOException{
    byte[] buffer = new byte[8*1024];
    int count = 0;
    int n = 0;

    while (-1 != (n = input.read(buffer))) {
        output.write(buffer, 0, n);
        count += n;
        publishProgress((int) (count * 100 / fileLength));
    }
    return count;
}

step 4:

to recycle the bitmap use:

bitmap.recycle();
bitmap = null;

call the function like resizeBitmap(context.getResources(), Measuredwidth, Measuredheight, THE_INPUTSTREAM_FROM_WHERE_YOU_ARE_DOWNLOADING_THE_IMAGE, FILELENGTH_FROM_THE_INPUTSTREAM);.

if you are calling the function from an activity the call it like: resizeBitmap(getResources(), Measuredwidth, Measuredheight, THE_INPUTSTREAM_FROM_WHERE_YOU_ARE_DOWNLOADING_THE_IMAGE, FILELENGTH_FROM_THE_INPUTSTREAM);

the function will return resized bitmap which will fit with the divice resulation. if you have already setted a bitmap as wallpaper, then don't forget to recycle the bitmap before you set a new bitmap as wallpaper.

Shoshi
  • 2,254
  • 1
  • 29
  • 43
  • @Jack : you r wellcome. let me know if you have any further problem :) – Shoshi Oct 05 '13 at 10:12
  • I am getting the images from the internet, Also, I'm getting an error on "getWindowManager" with "The method getWindowManager() is undefined for the type new View.OnClickListener(){}" and am getting an error on " Measuredwidth" and " Measuredheight" with "Measuredheight cannot be resolved to a variable" – Jack Oct 05 '13 at 11:15
  • @Jack : `The method getWindowManager() is undefined for the type new View.OnClickListener(){}` this is a very simple error. you have to write the code of `step 1` in `onCreate()` and not into `onClickListener()`. ok? then in `onClickLister` call `resizeBitmap()`. and declare `Measuredwidth` and `Measuredheight` at the very begining of your activity. i mean as a global variable for your activity. let me know what happen. :) – Shoshi Oct 05 '13 at 13:28
  • I am using a fragment by the way, and when putting the code "WindowManager w = context.getWindowManager();" it gives me error "The method getWindowManager() is undefined for the type Context" – Jack Oct 05 '13 at 13:38
  • @Jack : then use `getActivity().getWindowManager()`. replace all the `context.` with `getActivity().` in my answer. it will work. – Shoshi Oct 05 '13 at 14:48
  • Ok, that works fine, I have put that code in the onCreate. Check my updated answer to see where I am at now. I am confused where you said "then in onClickLister call resizeBitmap(). and declare Measuredwidth and Measuredheight at the very begining of your activity. i mean as a global variable for your activity." ? – Jack Oct 05 '13 at 15:26
  • @Jack : in which class you are downloading the image ? – Shoshi Oct 05 '13 at 16:08
  • I have updated it with my whole class code. I am getting the images with the current class linked with another class that controls the image displaying. – Jack Oct 05 '13 at 16:36
  • @Jack : excuse me, is this `BitmapFun` tutorial project from android.google ? – Shoshi Oct 05 '13 at 16:55
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/38666/discussion-between-shoshi-and-jack) – Shoshi Oct 05 '13 at 17:02
1

Please see the function and change the size according to your need. Thanks

public Bitmap createScaledImage(Bitmap bit) {

    Bitmap bitmapOrg = bit;

    int width = bitmapOrg.getWidth();
    int height = bitmapOrg.getHeight();
    int newWidth = 0, newHeight = 0;

    if (MyDevice.getInstance().getDeviceSize().equals("XLARGE")) {
        MyDevice.getInstance().SCALE = 65;
        newWidth = 65;
        newHeight = 65;

    } else if (MyDevice.getInstance().getDeviceSize().equals("LARGE")) {
        MyDevice.getInstance().SCALE = 60;
        newWidth = 60;
        newHeight = 60;

    }

    else if (MyDevice.getInstance().getDeviceSize().equals("NORMAL")) {
        MyDevice.getInstance().SCALE = 50;
        newWidth = 50;
        newHeight = 50;

        if (h > 800) {
            MyDevice.getInstance().SCALE = 60;
            newWidth = 60;
            newHeight = 60;
        }

    } else if (MyDevice.getInstance().getDeviceSize().equals("SMALL")) {
        MyDevice.getInstance().SCALE = 30;
        newWidth = 30;
        newHeight = 30;
    }

    float scaleWidth = ((float) newWidth) / width;
    float scaleHeight = ((float) newHeight) / height;

    Matrix matrix = new Matrix();
    // resize the bit map
    matrix.postScale(scaleWidth, scaleHeight);

    // recreate the new Bitmap
    Bitmap resizedBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0, width,
            height, matrix, true);

    return resizedBitmap;

}

Where MyDevice is a singleton class here. You can change it as you want. getdevicesize method determines what device it is.

AshMv
  • 392
  • 2
  • 12