安卓高斯模糊特效blur_demo(包含viewpager切换动画)



public class MainActivity extends FragmentActivity {//高斯模糊效果的主方法入口

private ViewPager viewPager;
private CustomPagerAdapter pagerAdapter;//自定义页面适配器
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.viewpager);
pagerAdapter =
                new CustomPagerAdapter(
                        getSupportFragmentManager());
viewPager.setAdapter(pagerAdapter);
viewPager.setPageTransformer(true, new ZoomOutPageTransformer());//切换的动画效果,缩放效果
}


public class CustomPagerAdapter extends FragmentStatePagerAdapter {


private ArrayList<Fragment> fragments = new ArrayList<Fragment>();


public CustomPagerAdapter(FragmentManager fm) {
super(fm);
fragments.add(Fragment.instantiate(MainActivity.this,
Fragment_First.class.getName()));
fragments.add(Fragment.instantiate(MainActivity.this,
Fragment_Two.class.getName()));
fragments.add(Fragment.instantiate(MainActivity.this,
Fragment_Three.class.getName()));
}


@Override
public Fragment getItem(int i) {
return fragments.get(i);
}


@Override
public int getCount() {
return fragments.size();
}


@Override
public CharSequence getPageTitle(int position) {
return fragments.get(position).toString();
}
}


}


//主界面布局文件代码如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"    
    android:orientation="vertical"
    >
    <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="40dp"
            android:background="@drawable/im_top_default_bk"
            android:gravity="center"
            android:orientation="vertical" >


            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="100dp"
                android:layout_marginRight="100dp"
                android:gravity="center"
                android:text="高斯模糊"
                android:textSize="25sp"
                android:textColor="#fff"
                 />
        </LinearLayout>
    <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="40dp"
            
            android:background="#fff"
            android:orientation="vertical" >


            <LinearLayout
                android:layout_width="fill_parent"
                android:layout_height="37dip"
                android:gravity="center"
                android:orientation="horizontal"
                android:weightSum="3" >


                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:gravity="center"
                    android:orientation="horizontal" >


                    <TextView
                        android:id="@+id/first_text"
                        android:layout_width="fill_parent"
                        android:layout_height="fill_parent"                        
                        android:gravity="center"
                        android:text="第一个"
                        android:textColor="@color/red"
                        android:textSize="18sp" />


                    
                </LinearLayout>


                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:orientation="horizontal" >


                    <TextView
                        android:id="@+id/sales_text"
                        android:layout_width="fill_parent"
                        android:layout_height="fill_parent"
                        android:gravity="center"
                        android:text="第二个"
                        android:textColor="@color/gray"
                        android:textSize="18sp" />
                </LinearLayout>


                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:orientation="horizontal" >


                    <TextView
                        android:id="@+id/moods_text"
                        android:layout_width="fill_parent"
                        android:layout_height="fill_parent"
                        android:gravity="center"
                        android:text="第三个"
                        android:textColor="@color/gray"
                        android:textSize="18sp" />
                </LinearLayout>
            </LinearLayout>


            <LinearLayout
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"               
                android:orientation="horizontal" >


                <ImageView
                    android:id="@+id/one_image"
                    android:layout_width="fill_parent"
                    android:layout_height="2dp"
                    android:layout_weight="1"
                    android:scaleType="fitXY"
                    android:src="@drawable/tab_line" />


                <ImageView
                    android:id="@+id/two_image"
                    android:layout_width="fill_parent"
                    android:layout_height="2dp"
                    android:layout_weight="1"
                    android:scaleType="fitXY" />


                <ImageView
                    android:id="@+id/three_image"
                    android:layout_width="fill_parent"
                    android:layout_height="2dp"
                    android:layout_weight="1"
                    android:scaleType="fitXY" />
            </LinearLayout>
        </LinearLayout>    
    
    <android.support.v4.view.ViewPager 
    android:id="@+id/viewpager"
    android:background="@color/light_grey"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    />


</LinearLayout>


//三个fragment页面代码如下:

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.blurdemo02.R;
import com.example.blurdemo02.util.FastBlur;
public class Fragment_First extends Fragment{
private View view;
private ImageView image;
TextView textView1;

@Override
   public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
       view = inflater.inflate(R.layout.fragment_first, container, false);
       image = (ImageView) view.findViewById(R.id.picture1);
       textView1= (TextView) view.findViewById(R.id.textView1);
       image.setImageResource(R.drawable.picture);
       applyBlur();
       return view;
   }

@Override
   public String toString() {
       return "First";
   }
private void applyBlur() {
       image.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
           @Override
           public boolean onPreDraw() {
               image.getViewTreeObserver().removeOnPreDrawListener(this);
               image.buildDrawingCache();


               Bitmap bmp = image.getDrawingCache();
               blur(bmp, textView1);
               return true;
           }
       });
   }


private void blur(Bitmap bkg, View view) {
       long startMs = System.currentTimeMillis();
       float scaleFactor = 1;
       float radius = 20;
       
       Bitmap overlay = Bitmap.createBitmap((int) (view.getMeasuredWidth() / scaleFactor),
               (int) (view.getMeasuredHeight() / scaleFactor), Bitmap.Config.ARGB_8888);
       Canvas canvas = new Canvas(overlay);
       canvas.translate(-view.getLeft() / scaleFactor, -view.getTop() / scaleFactor);
       canvas.scale(1 / scaleFactor, 1 / scaleFactor);
       Paint paint = new Paint();
       paint.setFlags(Paint.FILTER_BITMAP_FLAG);
       canvas.drawBitmap(bkg, 0, 0, paint);


       overlay = FastBlur.doBlur(overlay, (int) radius, true);
       view.setBackgroundDrawable(new BitmapDrawable(getResources(), overlay));
       
   }
 
}


//第一个fragment布局如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >


    <ImageView 
        android:id="@+id/picture1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        
        android:scaleType="centerCrop"
        />
    
    <TextView
        android:id="@+id/textView1"
        android:layout_width="match_parent"
        android:layout_height="200dip"
        android:gravity="center"
        android:layout_marginTop="35dip"
        android:text="Fragment_First"
        android:textColor="#fff"
        android:textAppearance="?android:attr/textAppearanceLarge" />


</RelativeLayout>

//以下代码为三个工具类FastBlur,ImageBlur,ZoomOutPageTransformer:

import android.graphics.Bitmap;
public class FastBlur {
    public static Bitmap doBlurJniArray(Bitmap sentBitmap, int radius, boolean canReuseInBitmap) {
        Bitmap bitmap;
        if (canReuseInBitmap) {
            bitmap = sentBitmap;
        } else {
            bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);
        }


        if (radius < 1) {
            return (null);
        }


        int w = bitmap.getWidth();
        int h = bitmap.getHeight();


        int[] pix = new int[w * h];
        bitmap.getPixels(pix, 0, w, 0, 0, w, h);
        //Jni 数组计算
        ImageBlur.blurIntArray(pix, w, h, radius);


        bitmap.setPixels(pix, 0, w, 0, 0, w, h);
        return (bitmap);
    }


    public static Bitmap doBlurJniBitMap(Bitmap sentBitmap, int radius, boolean canReuseInBitmap) {
        Bitmap bitmap;
        if (canReuseInBitmap) {
            bitmap = sentBitmap;
        } else {
            bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);
        }


        if (radius < 1) {
            return (null);
        }
        //Jni BitMap
        ImageBlur.blurBitMap(bitmap, radius);


        return (bitmap);
    }
    public static Bitmap doBlur(Bitmap sentBitmap, int radius, boolean canReuseInBitmap) {      
        Bitmap bitmap;
        if (canReuseInBitmap) {
            bitmap = sentBitmap;
        } else {
            bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);
        }


        if (radius < 1) {
            return (null);
        }


        int w = bitmap.getWidth();
        int h = bitmap.getHeight();


        int[] pix = new int[w * h];
        bitmap.getPixels(pix, 0, w, 0, 0, w, h);


        int wm = w - 1;
        int hm = h - 1;
        int wh = w * h;
        int div = radius + radius + 1;


        int r[] = new int[wh];
        int g[] = new int[wh];
        int b[] = new int[wh];
        int rsum, gsum, bsum, x, y, i, p, yp, yi, yw;
        int vmin[] = new int[Math.max(w, h)];


        int divsum = (div + 1) >> 1;
        divsum *= divsum;
        int dv[] = new int[256 * divsum];
        for (i = 0; i < 256 * divsum; i++) {
            dv[i] = (i / divsum);
        }


        yw = yi = 0;


        int[][] stack = new int[div][3];
        int stackpointer;
        int stackstart;
        int[] sir;
        int rbs;
        int r1 = radius + 1;
        int routsum, goutsum, boutsum;
        int rinsum, ginsum, binsum;


        for (y = 0; y < h; y++) {
            rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
            for (i = -radius; i <= radius; i++) {
                p = pix[yi + Math.min(wm, Math.max(i, 0))];
                sir = stack[i + radius];
                sir[0] = (p & 0xff0000) >> 16;
                sir[1] = (p & 0x00ff00) >> 8;
                sir[2] = (p & 0x0000ff);
                rbs = r1 - Math.abs(i);
                rsum += sir[0] * rbs;
                gsum += sir[1] * rbs;
                bsum += sir[2] * rbs;
                if (i > 0) {
                    rinsum += sir[0];
                    ginsum += sir[1];
                    binsum += sir[2];
                } else {
                    routsum += sir[0];
                    goutsum += sir[1];
                    boutsum += sir[2];
                }
            }
            stackpointer = radius;


            for (x = 0; x < w; x++) {


                r[yi] = dv[rsum];
                g[yi] = dv[gsum];
                b[yi] = dv[bsum];


                rsum -= routsum;
                gsum -= goutsum;
                bsum -= boutsum;


                stackstart = stackpointer - radius + div;
                sir = stack[stackstart % div];


                routsum -= sir[0];
                goutsum -= sir[1];
                boutsum -= sir[2];


                if (y == 0) {
                    vmin[x] = Math.min(x + radius + 1, wm);
                }
                p = pix[yw + vmin[x]];


                sir[0] = (p & 0xff0000) >> 16;
                sir[1] = (p & 0x00ff00) >> 8;
                sir[2] = (p & 0x0000ff);


                rinsum += sir[0];
                ginsum += sir[1];
                binsum += sir[2];


                rsum += rinsum;
                gsum += ginsum;
                bsum += binsum;


                stackpointer = (stackpointer + 1) % div;
                sir = stack[(stackpointer) % div];


                routsum += sir[0];
                goutsum += sir[1];
                boutsum += sir[2];


                rinsum -= sir[0];
                ginsum -= sir[1];
                binsum -= sir[2];


                yi++;
            }
            yw += w;
        }
        for (x = 0; x < w; x++) {
            rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
            yp = -radius * w;
            for (i = -radius; i <= radius; i++) {
                yi = Math.max(0, yp) + x;


                sir = stack[i + radius];


                sir[0] = r[yi];
                sir[1] = g[yi];
                sir[2] = b[yi];


                rbs = r1 - Math.abs(i);


                rsum += r[yi] * rbs;
                gsum += g[yi] * rbs;
                bsum += b[yi] * rbs;


                if (i > 0) {
                    rinsum += sir[0];
                    ginsum += sir[1];
                    binsum += sir[2];
                } else {
                    routsum += sir[0];
                    goutsum += sir[1];
                    boutsum += sir[2];
                }


                if (i < hm) {
                    yp += w;
                }
            }
            yi = x;
            stackpointer = radius;
            for (y = 0; y < h; y++) {
                // Preserve alpha channel: ( 0xff000000 & pix[yi] )
                pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] << 16) | (dv[gsum] << 8) | dv[bsum];


                rsum -= routsum;
                gsum -= goutsum;
                bsum -= boutsum;


                stackstart = stackpointer - radius + div;
                sir = stack[stackstart % div];


                routsum -= sir[0];
                goutsum -= sir[1];
                boutsum -= sir[2];


                if (x == 0) {
                    vmin[y] = Math.min(y + r1, hm) * w;
                }
                p = x + vmin[y];


                sir[0] = r[p];
                sir[1] = g[p];
                sir[2] = b[p];


                rinsum += sir[0];
                ginsum += sir[1];
                binsum += sir[2];


                rsum += rinsum;
                gsum += ginsum;
                bsum += binsum;


                stackpointer = (stackpointer + 1) % div;
                sir = stack[stackpointer];


                routsum += sir[0];
                goutsum += sir[1];
                boutsum += sir[2];


                rinsum -= sir[0];
                ginsum -= sir[1];
                binsum -= sir[2];


                yi += w;
            }
        }


        bitmap.setPixels(pix, 0, w, 0, 0, w, h);
        return (bitmap);
    }
}


import android.graphics.Bitmap;
public class ImageBlur {
    public static native void blurIntArray(int[] pImg, int w, int h, int r);


    public static native void blurBitMap(Bitmap bitmap, int r);


    static {
        System.loadLibrary("JNI_ImageBlur");
    }
}


import android.annotation.SuppressLint;
import android.support.v4.view.ViewPager;
import android.view.View;
public class ZoomOutPageTransformer implements ViewPager.PageTransformer {
    private static final float MIN_SCALE = 0.85f;
    private static final float MIN_ALPHA = 0.5f;
    @SuppressLint("NewApi")
public void transformPage(View view, float position) {
        int pageWidth = view.getWidth();
        int pageHeight = view.getHeight();


        if (position < -1) { // [-Infinity,-1)
            // This page is way off-screen to the left.
            view.setAlpha(0);


        } else if (position <= 1) { // [-1,1]
            // Modify the default slide transition to shrink the page as well
            float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
            float vertMargin = pageHeight * (1 - scaleFactor) / 2;
            float horzMargin = pageWidth * (1 - scaleFactor) / 2;
            if (position < 0) {
                view.setTranslationX(horzMargin - vertMargin / 2);
            } else {
                view.setTranslationX(-horzMargin + vertMargin / 2);
            }


            // Scale the page down (between MIN_SCALE and 1)
            view.setScaleX(scaleFactor);
            view.setScaleY(scaleFactor);


            // Fade the page relative to its size.
            view.setAlpha(MIN_ALPHA +
                    (scaleFactor - MIN_SCALE) /
                            (1 - MIN_SCALE) * (1 - MIN_ALPHA));

        } else { // (1,+Infinity]
            // This page is way off-screen to the right.
            view.setAlpha(0);
        }
    }
}



  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是Java中使用高斯模糊算法对Bitmap进行处理的代码示例: ```java public static Bitmap gaussianBlur(Bitmap src, float radius) { if (src == null) { return null; } int width = src.getWidth(); int height = src.getHeight(); int[] pixels = new int[width * height]; src.getPixels(pixels, 0, width, 0, 0, width, height); int[] resultPixels = new int[width * height]; System.arraycopy(pixels, 0, resultPixels, 0, pixels.length); int[] alpha = new int[256]; for (int i = 0; i < 256; i++) { alpha[i] = (int) (Math.exp(-((float) i * i) / (2 * radius * radius)) / (Math.sqrt(2 * Math.PI) * radius) * 255); } int[] box = new int[(int) (2 * radius)]; int boxWidth = (int) (radius / Math.sqrt(2 * Math.log(255))); int boxSize = boxWidth * 2 + 1; for (int i = 0; i < boxSize; i++) { box[i] = alpha[(int) (255 * i / boxSize)]; } for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int red = 0; int green = 0; int blue = 0; int alphaSum = 0; for (int i = -boxWidth; i <= boxWidth; i++) { int pixelIndex = x + clamp(i, 0, width - 1) + y * width; int pixel = pixels[pixelIndex]; int coeff = box[Math.abs(i)]; red += Color.red(pixel) * coeff; green += Color.green(pixel) * coeff; blue += Color.blue(pixel) * coeff; alphaSum += Color.alpha(pixel) * coeff; } int resultPixelIndex = x + y * width; resultPixels[resultPixelIndex] = Color.argb(alphaSum >> 8, red >> 8, green >> 8, blue >> 8); } } Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); result.setPixels(resultPixels, 0, width, 0, 0, width, height); return result; } private static int clamp(int value, int min, int max) { return Math.max(min, Math.min(value, max)); } ``` 其中,使用了以下公式计算高斯函数的系数: ``` alpha[i] = exp(-i^2 / (2 * radius^2)) / (sqrt(2 * PI) * radius) * 255 ``` 对于每个像素点,都会计算出一个以该像素点为中心的正方形框,框内像素点的加权平均值作为该像素点的值。每个像素点的加权系数使用上述公式计算得到。在处理边缘像素点时,使用了clamp函数将超出边界的像素点坐标限制在合法范围内。最后,将处理后的像素数组生成为一个新的Bitmap并返回。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值