Question

I trying to achieve water reflection effect on bitmap. As I saw some apps called water reflection. I know how to do the reflection of the image but the wave on the image is what making me confused on how it is done.

see this image for example

enter image description here

I did many apps on bitmap manipulation but this is quite hard to achieve. So any idea on where to start. Just an idea to start can be helpful.

Was it helpful?

Solution

For any one needed, I tried some simple tricks to get as closer as water reflection effect. It is not great but it looks fine to me.

I used two methods

Bitmap reflection method (give bitmap as a parameter)

  public static Bitmap Reflection(Bitmap imageBitmap) {

           int width = imageBitmap.getWidth();
           int height = imageBitmap.getHeight();

           Matrix matrix = new Matrix();
           matrix.preScale(1, -1);

          Bitmap reflectionImage = Bitmap.createBitmap(imageBitmap, 0,
                   0, width, height , matrix, false);

          Bitmap newbit=Bitmap.createScaledBitmap(reflectionImage, reflectionImage.getWidth()/8, reflectionImage.getHeight()/8, true);

          Bitmap newbit1=Bitmap.createScaledBitmap(newbit, newbit.getWidth()*8, newbit.getHeight()*8, true);

          Bitmap scalednew=Bitmap.createScaledBitmap(newbit1, width, height-(height/4), true);

          Bitmap newscaledone=overlay(scalednew);

       reflectionImage=newscaledone;

           Bitmap reflectedBitmap = Bitmap.createBitmap(width,
                   (height + height), Config.ARGB_8888);

           Canvas canvas = new Canvas(reflectedBitmap);
           canvas.drawBitmap(imageBitmap, 0, 0, null);
           Paint defaultPaint = new Paint();
           canvas.drawRect(0, height, width, height, defaultPaint);

           canvas.drawBitmap(reflectionImage, 0, height , null);
           Paint paint = new Paint();

           paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
           canvas.drawRect(0, height, width, reflectedBitmap.getHeight()
                    , paint);
               return reflectedBitmap;

}

Bitmap overlay method. I am taking a wave bitmap with some opacity to overlay on the reflected image. So that it may look like water.

 Bitmap wavebitmap=BitmapFactory.decodeResource(getResources(), R.drawable.waves1);

private static Bitmap overlay( Bitmap bmp2) {
     Bitmap bmp1=WaterReflectionMainActivity.wavebitmap;

      Bitmap bmp1new =Bitmap.createScaledBitmap(bmp1, bmp2.getWidth(), bmp2.getHeight(), true);

        Bitmap bmOverlay = Bitmap.createBitmap(bmp1new.getWidth(), bmp1new.getHeight(), bmp1new.getConfig());
        Canvas canvas = new Canvas(bmOverlay);
        canvas.drawBitmap(bmp2, new Matrix(), null);
        canvas.drawBitmap(bmp1new, new Matrix(), null);
        return bmOverlay;
    }

Well this is my version of water effect, I know this looks shit. So if anyone still got some better effect please share your code . thank you

OTHER TIPS

Tutorial related to this: http://www.xaraxone.com/webxealot/workbook34/page_4.htm Also have a read at this question: Add water effect on bitmap android. Have a read at both of them, i hope you will get an idea from this

You may also want to look through these: 1, 2, 3

This is just an idea but basically, what you need is to apply a deformation on the bottom part of the image, meaning that for each pixel on the bottom half, you compute a position to get it's color from the top picture.

Here's a pseudo code to give you a hint :

for (int x = 0;  x < width; x++) {

    for (int y = 0; y < img.height; y++) {

        // Compute a position on the original image
        // tweak the values heres to get the effect you want
        sourceX = x + (int) (cos(10000.0 / y) * 20); 
        sourceY = img.height - y - 1 +(int)( sin(y* 0.5) * 20); 

        // Maybe check the range of sourceX and source Y

        int color = img.getColor(sourceX, sourceY) 

        outptut.setColor(x, y + img.height, color); 
   }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top