1,在项目中我们常有这样的需求,就是在个人中心的时候,当用户登录后,要显示用户登陆后的头像,然后背景是用户头像的虚化 ,接下来就来实现一下这个功能,先看一下效果

2,实现起来也挺简单的,没什么难度 ,不多说,直接上代码

contain_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rl_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.wangjitao.bluedemotest.MainActivity"
tools:showIn="@layout/activity_main">
<ImageView
android:id="@+id/imageview_ll"
android:layout_width="match_parent"
android:layout_height="300dp"
android:scaleType="fitXY"
/>
<ImageView
android:id="@+id/imageview"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_centerInParent="true"
/>
</RelativeLayout>

 MainActivity.java

package com.wangjitao.bluedemotest;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.renderscript.Allocation;
import android.renderscript.RenderScript;
import android.renderscript.ScriptIntrinsicBlur;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.RelativeLayout; import com.squareup.picasso.Picasso; public class MainActivity extends AppCompatActivity {
private Context mContext = MainActivity.this;
private ImageView imageView ;
private ImageView imageview_ll ;
private RelativeLayout mRelativeLayout ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar); FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
}); initView();
} private void initView() {
imageView = (ImageView) findViewById(R.id.imageview);
imageview_ll = (ImageView) findViewById(R.id.imageview_ll);
mRelativeLayout = (RelativeLayout) findViewById(R.id.rl_content);
Picasso.with(mContext)
.load(R.mipmap.img_feed_sakura)
.placeholder(R.drawable.img_circle_placeholder)
.resize(getResources().getDimensionPixelSize(R.dimen.global_menu_avatar_size),
getResources().getDimensionPixelSize(R.dimen.global_menu_avatar_size))
.centerCrop()
.transform(new CircleTransformation())
.into(imageView);
Bitmap bkg = BitmapFactory.decodeResource(getResources(), R.mipmap.img_feed_sakura); imageview_ll.setImageBitmap(fastblur(bkg,10));
//blur(bkg,mRelativeLayout,20f); }
private void blur(Bitmap bkg, View view, float radius) { //view.getMeasuredWidth() view.getMeasuredHeight()
Bitmap overlay = Bitmap.createBitmap(view.getMeasuredWidth(),view.getMeasuredHeight() , Bitmap.Config
.ARGB_8888);
Canvas canvas = new Canvas(overlay);
canvas.drawBitmap(bkg, -view.getLeft(), -view.getTop(), null);
RenderScript rs = RenderScript.create(this);
Allocation overlayAlloc = Allocation.createFromBitmap(rs, overlay);
ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(rs, overlayAlloc.getElement());
blur.setInput(overlayAlloc);
blur.setRadius(radius);
blur.forEach(overlayAlloc);
overlayAlloc.copyTo(overlay);
view.setBackground(new BitmapDrawable(getResources(), overlay));
rs.destroy();
} /*
* This method was copied from http://stackoverflow.com/a/10028267/694378.
* The only modifications I've made are to remove a couple of Log
* statements which could slow things down slightly.
*/
public Bitmap fastblur(Bitmap sentBitmap, int radius) { // Stack Blur v1.0 from
// http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html
//
// Java Author: Mario Klingemann <mario at quasimondo.com>
// http://incubator.quasimondo.com
// created Feburary 29, 2004
// Android port : Yahel Bouaziz <yahel at kayenko.com>
// http://www.kayenko.com
// ported april 5th, 2012 // This is a compromise between Gaussian Blur and Box blur
// It creates much better looking blurs than Box Blur, but is
// 7x faster than my Gaussian Blur implementation.
//
// I called it Stack Blur because this describes best how this
// filter works internally: it creates a kind of moving stack
// of colors whilst scanning through the image. Thereby it
// just has to add one new block of color to the right side
// of the stack and remove the leftmost color. The remaining
// colors on the topmost layer of the stack are either added on
// or reduced by one, depending on if they are on the right or
// on the left side of the stack.
//
// If you are using this algorithm in your code please add
// the following line:
//
// Stack Blur Algorithm by Mario Klingemann <mario@quasimondo.com> Bitmap 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);
}
}

 CircleTransformation.java

package com.wangjitao.bluedemotest;

import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint; import com.squareup.picasso.Transformation; public class CircleTransformation implements Transformation { private static final int STROKE_WIDTH = 6; @Override
public Bitmap transform(Bitmap source) {
int size = Math.min(source.getWidth(), source.getHeight()); int x = (source.getWidth() - size) / 2;
int y = (source.getHeight() - size) / 2; Bitmap squaredBitmap = Bitmap.createBitmap(source, x, y, size, size);
if (squaredBitmap != source) {
source.recycle();
} Bitmap bitmap = Bitmap.createBitmap(size, size, source.getConfig()); Canvas canvas = new Canvas(bitmap); Paint avatarPaint = new Paint();
BitmapShader shader = new BitmapShader(squaredBitmap, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
avatarPaint.setShader(shader); Paint outlinePaint = new Paint();
outlinePaint.setColor(Color.WHITE);
outlinePaint.setStyle(Paint.Style.STROKE);
outlinePaint.setStrokeWidth(STROKE_WIDTH);
outlinePaint.setAntiAlias(true); float r = size / 2f;
canvas.drawCircle(r, r, r, avatarPaint);
canvas.drawCircle(r, r, r - STROKE_WIDTH / 2, outlinePaint); squaredBitmap.recycle();
return bitmap;
} @Override
public String key() {
return "circleTransformation()";
}
}

  

 

 

Android -- 背景虚化的更多相关文章

  1. opencv在手机上实现照片背景虚化

    概述 使用androidstudio开发,在手机上实现照片背景虚化 详细 代码下载:http://www.demodashi.com/demo/10599.html 一.准备工作 1.需要下载安装an ...

  2. opencv图像处理之在手机上实现背景虚化

    http://m.blog.csdn.net/blogercn/article/details/75004162 1.高端数码相机都具有背景虚化功能.背景虚化就是使景深变浅,使焦点聚集在主题上.一般的 ...

  3. UIView点击事件。弹出视图,背景虚化。

    @interface CountryViewController //背景 @property (strong, nonatomic) UIView *BackView; end //设置背景虚化 - ...

  4. 背景虚化 Google Camera App Nokia Refocus HTC One M8 的 Duo景深相机

    背景虚化是单反中一种比较常见的拍照形式,参看 http://www.techbang.com/posts/%2017842 https://refocus.nokia.com/

  5. 第01讲- Android背景知识

    第01讲Android背景知识 Android是基于Linux系统 Android系统框图 : 第一.操作系统层(OS) 第二.各种库(Libraries)和Android 运行环境(RunTime) ...

  6. android背景选择器selector用法汇总

    一.创建xml文件,位置:drawable/xxx.xml,同目录下记得要放相关图片 <?xml version="1.0" encoding="utf-8&quo ...

  7. Android 背景图片重复平铺

    有时候我们需要将一个图片横向或者纵向的平铺(重复循环),这个时候我们需要创建一个xml文件,如下: <?xml version ="1.0" encoding =" ...

  8. 【转】java代码中实现android背景选择的selector-StateListDrawable的应用

    原文网址:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/0924/1712.html 下面的代码应该很多人都熟悉: 1 2 3 ...

  9. android背景平铺方式 tileMode

    创建重复的背景图片  在drawable目录下创建一个repeat_bg.xml:    然后在布局的xml文件中可以这样引用:    ================================ ...

随机推荐

  1. NRF51822之GPIOTE介绍

    Note This library is obsolete and should not be used in new designs. Instead, you should use GPIOTE ...

  2. ArcGIS API for Silverlight 调用WebService出现跨域访问报错的解决方法

    原文:ArcGIS API for Silverlight 调用WebService出现跨域访问报错的解决方法 群里好几个朋友都提到过这样的问题,说他们在Silverlight中调用了WebServi ...

  3. Java实验三报告

    一.  实验内容 (一)敏捷开发与XP 摘要:一项实践在XP环境中成功使用的依据通过XP的法则呈现,包括:快速反馈.假设简单性.递增更改.提倡更改.优质工作.XP软件开发的基石是XP的活动,包括:编码 ...

  4. opencv的高斯混合模型

    http://blog.jasonding.top/2015/04/05/Machine%20Learning/%E3%80%90%E8%AE%A1%E7%AE%97%E6%9C%BA%E8%A7%8 ...

  5. Linux脚本执行过程重定向

    Linux脚本执行过程重定向 一.bash调试脚本,并将执行过程重定向到指定文件 bash –x  shell.sh 2>&1 | tee shell.log

  6. MySQL学习笔记——存储引擎的索引特性

  7. Linux中的元字符和转义符 单引号 硬引号 双引号 软引号

    Linux中的元字符和转义符  单引号  硬引号  双引号  软引号 Linux就这个范儿 Linux就这个范儿 P182单引号:硬引号,所有元字符特殊意义都会关掉双引号:软引号,只允许出现特定元字符 ...

  8. 小白教你玩转php的闭包

    php5.3有一个非常赞的新特性,那就是支持匿名函数(闭包).匿名函数可用于动态创建函数,并保存到一个变量中.举个栗子: $func = function(){ exit('Hello world!! ...

  9. you need to upgrade the working copy first

    is too old (format 29) to work with client version '1.9.4 (r1740329)' (expects format 31) 2016年09月18 ...

  10. sqlite数据库 adb 从配置到查询表中数据全过程-----献给初学的自己

    1.   E:\Android\android-sdk-windows\platform-tools[将adb.exe文件的路径放到path中,设置环境变量] 2.  adb -s emulator ...