GeorgeYang'Blog

my technology blog


2015年末新版skype中,如果用户没有设置头像,那么skype就会给用户生成一个头像,生成规则如下:如果用户名是george.yang,那么他的头像是G(文字大写居中)加指定的背景色。 在我们的app中需要加这个功能,app使用图片加载框架是facebook的Fresco,Fresco给用户自定义加载的能力很差,建议以后不要使用它了~

步骤1:准备后处理器

 public class UserHeadPostprocessor extends BasePostprocessor {
     private String userName;
     public UserHeadPostprocessor (String userName) {
         this.userName = userName;
     }

     @Override
     public String getName() {
         return "userHeadPostprocessor";
     }

     @Override
     public void process(Bitmap bitmap) {
         char chr = userName.toUpperCase().charAt(0);
         int bgColor = getColor(chr);

         //图象大小要根据文字大小算下,以和文本长度对应
         Canvas canvasTemp = new Canvas(bitmap);
         canvasTemp.drawColor(bgColor);
     }

参考:http://fresco-cn.org/docs/modifying-image.html

步骤2:获取大写字母对应的背景色

要让每个字母对应一个颜色,总不能真的准备26张图吧?不对是27张,如果用户名已字母开头或其他国家的文字开头,那么不属于a-z的统一为一种颜色,总共26+1,27种颜色,所以我们要生成27种颜色,颜色由RGB三个基本颜色构成,在android中表示是#ARGB,每个字母是0-254的16进制表示的,如果是不透明全白色,则表示成#FFFFFFFF,那么不算透明度,有3种数值可以构成颜色,有趣的是3^3=27,如果每种颜色分成3段,那么长度为3的3进制刚好可以把颜色拼起来,代码如下:

  private int getColor(char chr) {
         String coloIndexs;
         if (chr>='A' && chr <='Z') {
             coloIndexs = Integer.toString(chr-'A',3);
         } else {
             coloIndexs= Integer.toString(27,3);
         }
         if (coloIndexs.length()==1) {
             coloIndexs = "00"+coloIndexs;
         } else if (coloIndexs.length()==2) {
             coloIndexs = "0"+coloIndexs;
         }
         StringBuilder sb = new StringBuilder("#FF");
         for (char ch:coloIndexs.toCharArray()) {
             int colorCut = 0;
             //255/3=85 (0-85,86-170,170-255)
             if (ch=='1') {
                 colorCut = 70;
             } else if (ch == '2') {
                 colorCut = 150;
             } else {
                 colorCut = 230;
             }
             String colorCut16 = Integer.toHexString(colorCut).toUpperCase();
             sb.append(colorCut16);
         }
         int bgColor = Color.parseColor(sb.toString());
         return bgColor;
     }

博客出处 参考: http://cavonchen.iteye.com/blog/626318 http://blog.csdn.net/is_zhoufeng/article/details/8544246 http://blog.csdn.net/you23hai45/article/details/18330325

步骤3:画文字,居中

     public void process2(Bitmap bitmap) {
         char chr = userName.toUpperCase().charAt(0);
         int bgColor = getColor(chr);

         //图象大小要根据文字大小算下,以和文本长度对应
         Canvas canvasTemp = new Canvas(bitmap);
         canvasTemp.drawColor(bgColor);
         Paint p = new Paint();
         p.setColor(Color.BLACK);
         Typeface font = Typeface.create("宋体", Typeface.BOLD);
         p.setTypeface(font);
         p.setAntiAlias(true);//去除锯齿
         p.setFilterBitmap(true);//对位图进行滤波处理
         p.setTextSize(bitmap.getWidth());

         Rect rect = new Rect();
         p.getTextBounds(String.valueOf(chr), 0, 1, rect);

          canvasTemp.drawText(String.valueOf(chr),bitmap.getWidth()/2f-rect.width()/2f,bitmap.getHeight()/2f-rect.height()/2f,p);
     }

参考: http://blog.csdn.net/leolaurel/article/details/7719759

步骤4:设置预处理器

 Uri uri = new Uri.Builder()).scheme("res").path(String.valueOf(R.drawable.home_page_upload_icon)).build()
 //把资源文件转成uri,给它加载,不然不会交给后处理器处理啊~
    ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
                    .setPostprocessor(new UserHeadPostprocessor(userName))
                    .build();

            PipelineDraweeController controller = (PipelineDraweeController)
                    Fresco.newDraweeControllerBuilder()
                            .setImageRequest(request)
                            .setOldController(userHead.getController())
                            .build();

            userHead.setController(controller);

参考:http://www.bubuko.com/infodetail-1003701.html