位图上的水面反射效果

3
我想在位图上实现水反射效果,就像一些应用程序所称的水反射。我知道如何对图像进行反射,但是图像上的波浪是让我困惑的东西,不知道如何实现。
以这张图片为例:
https://istack.dev59.com/XJEUp.webp 我已经开发了很多有关位图处理的应用程序,但这个问题很难解决。有什么建议吗?只要有一个起点的想法就可以帮助我了。

你有解决方案吗?我也遇到了同样的问题。 - Butani Vijay
你找到如何创建帧以生成gif文件或mp4的解决方案了吗?我也有同样的问题。我可以创建一个波纹位图,但找不到任何方法来产生移动波浪并创建帧。你能帮我吗? - R1349
Butani,我看到你也在寻找这个问题的解决方案,你找到了吗? - R1349
4个回答

3

对于需要的人,我尝试了一些简单的技巧来实现水面倒影效果。虽然并不完美,但在我的看来还是不错的。

我使用了两种方法:

1. 位图反射方法(将位图作为参数)

  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 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;
    }

这是我的水效果版本,我知道看起来很差。 如果有人有更好的效果,请分享你的代码。 谢谢。


你能提供你使用的波形图像吗? - Gaurav Agrawal

2

这只是一个想法,但基本上,您需要对图像的底部应用变形,也就是说,对于底半部分的每个像素,您需要计算出一个位置,从顶部图片中获取其颜色。

以下是伪代码以供参考:

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); 
   }
}

我有一个疑问。在倒数第二行中的 "img.get" 中,我们在尝试获取什么? - Sandeep R
img 是你想要添加反射的原始图像。img.get 实际上是获取源点 sourceX、sourceY 处的颜色。output.set 实际上是 output.setColor(我会相应地编辑我的答案)。 - XGouchet
我认为代码有问题。我在int color行上遇到了错误。 - Sandeep R
在Android中,应该使用img.getPixel而不是img.getcolor。 - Sandeep R
是的,正如我所说的,这只是伪代码,因为我只在Processing中进行了测试(没有时间设置完整的应用程序测试来修改图像)。 - XGouchet

2

但是目前还没有指向Android的水效果教程。不过有一些好的链接资源。 - Sandeep R
@sandeep 通过Android应该是类似的,你介意给我的回答打个勾吗? - Daksh Shah
是的,我会等待更多更接近的答案,然后标记帮助我实现目标的答案。我一定会点赞你的答案,因为它有一些好的来源。 - Sandeep R

1

我已经尝试过遮罩,但它看起来不像水效果。但还是谢谢你的回答。 - Sandeep R
你提供的参考链接都是涟漪效果,比如用于动态壁纸或动画。但我想在静态位图图像上实现水波效果。 - Sandeep R
是的,我知道,但我认为这可以帮助你理解逻辑,所以我发了帖。 - Hardik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接