2

How can I apply an alpha gradient on an image so that it fades linearly? Right now, I'm creating rectangles of unit width and using it to draw the bitmap with a paint object with alpha value being changed in a loop. I only did it since I couldn't think of anything else. So a neater way would be better.

Bitmap bitmap = BitmapFactory.decodeStream(is);
Bitmap bmp = Bitmap.createScaledBitmap(bitmap, 100, 151, true));
bitmap.recycle();

Rect Rect1 = new Rect(0, 0, 100, 100);
Rect Rect2 = new Rect(100, 0, 101, 100);

Paint paint = new Paint();

canvas.drawBitmap(bmp, Rect1, Rect1, null);
while (paint.getAlpha() != 0) {
    paint.setAlpha(paint.getAlpha() - 5);
    canvas.drawBitmap(bmp, Rect2, Rect2, paint);
    Rect2.set(Rect2.left + 1, Rect2.top, Rect2.right + 1, Rect2.bottom);
}

Something like this

Picture Alpha Gradient

P.S. I'm trying to do this for a live wallpaper.

timemanx
  • 4,493
  • 6
  • 34
  • 43
  • Have You tried GradientDrawable? Probably it possible to put it above with transparency... – sandrstar Aug 28 '12 at 01:46
  • @sandrstar I want to apply a gradient to the image so that anything behind it is visible. I think what you're saying is I can put a colour gradient over the image using GradientDrawable? – timemanx Aug 28 '12 at 02:51
  • this can be done with opengl, but i doubt you want to go down that path. – WIllJBD Aug 28 '12 at 03:43
  • the other way is if you can get the width and height of your bitmap, you can edit each row of pixels' alpha values by what ever you specify in a loop. This I think is the most direct way. – WIllJBD Aug 28 '12 at 03:46
  • @TimeManx right. At least You could try to. Or You could take a look at GradientDrawable sources for possible implementation ideas. – sandrstar Aug 28 '12 at 04:05
  • @WIllJBD I've worked with opengl before. not too much though. just point me in the right direction & I'll find the way. – timemanx Aug 28 '12 at 04:06
  • @sandrstar I tried an ImageView with an image as a background and a GradientDrawable as the src. I set the start colour as FFFFFFFF and end colour as 00FFFFFF. It didn't work. Did I do it correctly? – timemanx Aug 29 '12 at 11:58
  • Strange. I've just tried it under test project and it works fine. Will upload code and result. – sandrstar Aug 29 '12 at 13:16

2 Answers2

9

Probably, desired behaviour could be meet with only views manipulations. For it You should:

  • Prepare shape drawable

res/drawable/gradient_shape.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <gradient
            android:startColor="#00FFFFFF"
            android:endColor="#FFFFFFFF"
            android:type="linear" />
</shape>
  • Define layout: activity_main.xml:

    <ImageView
        android:id="@+id/photo"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/photo"
        android:src="@drawable/gradient_shape" />
    

    here drawable/photo is just jpeg in drawables folder;

  • Some suggests to add the following code to the activity (it, actually, depends on device native configuration and seems to be redundant for nowadays > 3.0 devices):

    public void onAttachedToWindow() {
         super.onAttachedToWindow();
         Window window = getWindow();
         window.setFormat(PixelFormat.RGBA_8888);
     }
    

After that I've observed the following on my 4.1 device: Sample image

It looks like gradient. I'm still not sure if it's what You're looking for.

sandrstar
  • 12,503
  • 8
  • 58
  • 65
  • That's what I'm getting too. But if I have an image as a background set for the layout, I want that to start becoming visible rather than the colour. Added a picture showing what I want. – timemanx Aug 29 '12 at 13:54
  • Have tried some stuff with custom view and Shaders (smth like here http://stackoverflow.com/questions/5231260/android-shader-behave-different-in-ondrawcanvas-and-new-canvasbitmap , like add alpha channel to decoded image and try to draw it with gradient shader), but unfortunately have not enough time to work out complete solution. Have You tried this way? – sandrstar Sep 18 '12 at 05:08
  • thanks for the link. i havent tried it yet. i switched to opengl since canvas was too slow for this and some other stuff i was trying to do. i'll try it and get back to you. – timemanx Sep 18 '12 at 19:45
1

Sometimes using the foreground attribute is not the best for the gradient, especially if using a motionlayout or you have nested scrollviews. The gradient on the foreground will disappear. Create an entirely new imageview, constrain it on the original, and set the background to the gradient.

XML With Both Imageviews

<ImageView
        android:id="@+id/main_imageView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:scaleType="centerCrop"
        android:src="@drawable/peakpx__1_"
        ads:layout_constraintHeight_percent=".55"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/main_imageView_gradient"
        android:layout_width="0dp"
        android:layout_height="0dp"
        ads:layout_constraintHeight_percent=".55"
        android:background="@drawable/gradient_theme_background"
        app:layout_constraintEnd_toEndOf="@id/main_imageView"
        app:layout_constraintBottom_toBottomOf="@id/main_imageView"
        app:layout_constraintStart_toStartOf="@id/main_imageView" />

Then for the gradient, I use black #000000 for darker themes, and white #ffffff for lighter ones. A lot of answers I see on this are not adding the center color. This is important if you want to have the gradient start closer to the bottom of the image.

gradient_background

<?xml version="1.0" encoding="utf-8"?>

<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >

<gradient
    android:angle="270"
    android:type="linear"
    android:endColor="#ff000000"
    android:centerColor="#00000000"
    android:startColor="#00000000"/>
</shape>