Search code examples
androidimagelayoutbackgroundsd-card

creating a drawable from sd card to set as a background in android


I am trying to use an image from the sd card and set it as the background for a relativelayout. I have tried other solutions that i have found here and elsewhere but they havent seemed to work for me. here is my code. I have commented out other ways that i have tried and didnt work. the only thing that worked for me was using setBackgroudnResource and using a resource from the app, but this was just to test to make sure mRoot was set up correctly. when I have tried all the other ways, it just doesn't set anything. Anyone know what I am doing wrong, or if there is a better way to do this?

        //one way i tired...
//String extDir = Environment.getExternalStorageDirectory().toString();
//Drawable d = Drawable.createFromPath(extDir + "/pic.png");
//mRoot.setBackgroundDrawable(d);

//another way tried..
//Drawable d = Drawable.createFromPath("/sdcard/pic.png");
//mRoot.setBackgroundDrawable(d);

//last way i tried...
mRoot.setBackgroundDrawable(Drawable.createFromPath(new File(Environment.getExternalStorageDirectory(), "pic.png").getAbsolutePath()));

//worked, only to verify mRoot was setup correctly and it could be changed
//mRoot.setBackgroundResource(R.drawable.bkg);

Solution

  • You do not load a drawable from SD card but a bitmap. Here is a method to load it with the reduced sampling (quality) so the program will not complain if the image is too large. Then I guess you need to process this bitmap i.e. crop it and resize for the background.

             // Read bitmap from Uri
         public Bitmap readBitmap(Uri selectedImage) {
             Bitmap bm = null;
             BitmapFactory.Options options = new BitmapFactory.Options();
             options.inSampleSize = 2; //reduce quality 
             AssetFileDescriptor fileDescriptor =null;
             try {
                 fileDescriptor = this.getContentResolver().openAssetFileDescriptor(selectedImage,"r");
             } catch (FileNotFoundException e) {
                 e.printStackTrace();
             }
             finally{
                 try {
                     bm = BitmapFactory.decodeFileDescriptor(fileDescriptor.getFileDescriptor(), null, options);
                     fileDescriptor.close();
                 } catch (IOException e) {
                     e.printStackTrace();
                 }
             }
             return bm;
         }
    

    The Uri here can be supplied from a gallery picker activity.

    The image then can be saved into application resources and loaded into an imageView

            private void saveBackground(Bitmap Background) {
            String strBackgroundFilename = "background_custom.jpg";
            try {
                Background.compress(CompressFormat.JPEG, 80, openFileOutput(strBackgroundFilename, MODE_PRIVATE));
            } catch (Exception e) {
                Log.e(DEBUG_TAG, "Background compression and save failed.", e);
            }
    
            Uri imageUriToSaveCameraImageTo = Uri.fromFile(new File(BackgroundSettings.this.getFilesDir(), strBackgroundFilename));
    
            // Load this image
            Bitmap bitmapImage = BitmapFactory.decodeFile(imageUriToSaveCameraImageTo.getPath());
            Drawable bgrImage = new BitmapDrawable(bitmapImage);
    
            //show it in a view
            ImageView backgroundView = (ImageView) findViewById(R.id.BackgroundImageView);
            backgroundView.setImageURI(null); 
            backgroundView.setImageDrawable(bgrImage);
        }