Launcher2 快捷方式图标的圆角处理及解析

              依然是针对Launcher2的代码解析,并且是关于创建的快捷方式图标的一点代码解析和后期处理方式。

               直接看代码,Utilities.java,因为快捷方式图标绘制最后返回的bitmap对象是在这个类中完成的,在之前的博客也提到过可以给应用图标添加统一的背景图,同样的在这个类中实际也是可以实现的。

               直接上代码,其中增加了添加统一背景的代码,可以结合之前的文章参考来做,效果是一样的。

                这次主要来解析下下面这个函数的过程

               

	/**
	 * Returns a bitmap suitable for the all apps view.
	 */
	static Bitmap createIconBitmap(Drawable icon, Context context) {
		synchronized (sCanvas) { // we share the statics :-(
			if (sIconWidth == -1) {
				initStatics(context);
			}
                        //将icon的默认宽和高赋值给width和height,sIconWidth,sIconHeight的定义可以在代码中找到
			int width = sIconWidth;
			int height = sIconHeight;

			if (icon instanceof PaintDrawable) {
				PaintDrawable painter = (PaintDrawable) icon;
				painter.setIntrinsicWidth(width);
				painter.setIntrinsicHeight(height);
			} else if (icon instanceof BitmapDrawable) {
				// Ensure the bitmap has a density. //直接从Drawable中获取bitmap对象
				BitmapDrawable bitmapDrawable = (BitmapDrawable) icon;
				Bitmap bitmap = bitmapDrawable.getBitmap();

				BitmapDrawable bitmapDrawable = (BitmapDrawable) icon;
				Bitmap bitmap = bitmapDrawable.getBitmap();
                                //设置icon的适配DPI参数,可忽略
				if (bitmap.getDensity() == Bitmap.DENSITY_NONE) {
					bitmapDrawable.setTargetDensity(context.getResources()
							.getDisplayMetrics());
				}
			}
                        //获取适配的应用图标实际大小,正常情况下会有三个尺寸48*48,72*72,96*96
			int sourceWidth = icon.getIntrinsicWidth();
			int sourceHeight = icon.getIntrinsicHeight();
			if (sourceWidth > 0 && sourceHeight > 0) {
				// There are intrinsic sizes.
				if (width < sourceWidth || height < sourceHeight) {
					// It's too big, scale it down.
                                        //应用图标尺寸大于默认尺寸,则默认尺寸按比例缩放至应用图标的宽高比例
					final float ratio = (float) sourceWidth / sourceHeight;
					if (sourceWidth > sourceHeight) {
						height = (int) (width / ratio);
					} else if (sourceHeight > sourceWidth) {
						width = (int) (height * ratio);
					}
				} else if (sourceWidth < width && sourceHeight < height) {
					// Don't scale up the icon
                                        //应用图标大小小于默认给定大小,不进行裁剪缩放
					width = sourceWidth;
					height = sourceHeight;
				}
			}
                        //默认icon图标大小
			// no intrinsic size --> use default size
			int textureWidth = sIconTextureWidth;
			int textureHeight = sIconTextureHeight;
                        //创建画布为默认icon大小
			final Bitmap bitmap = Bitmap.createBitmap(textureWidth,
					textureHeight, Bitmap.Config.ARGB_8888);
			final Canvas canvas = sCanvas;
			canvas.setBitmap(bitmap);
                        
			final int left = (textureWidth - width) / 2;
			final int top = (textureHeight - height) / 2;

			@SuppressWarnings("all")
			// suppress dead code warning
			final boolean debug = false;
			if (debug) {
				// draw a big box for the icon for debugging
				canvas.drawColor(sColors[sColorIndex]);
				if (++sColorIndex >= sColors.length)
					sColorIndex = 0;
				Paint debugPaint = new Paint();
				debugPaint.setColor(0xffcccc00);
				canvas.drawRect(left, top, left + width, top + height,
						debugPaint);
			}
/**
 * 添加统一背景,另一种方案,简单说就是利用一个现有的bitmap创建一个画布,并将图标画在这个画布上,实现增加背景的功能투ᅪ뾰ᄏᄆᄈᄒᄚ
 */
/*			if (true) {
				Bitmap backBitmap = BitmapFactory.decodeResource(
						context.getResources(), R.drawable.icon_bg);
				int backWidth = backBitmap.getWidth();
				int backHeight = backBitmap.getHeight();
				if (backWidth != sIconWidth || backHeight != sIconHeight) {
					Matrix matrix = new Matrix();
					matrix.postScale((float) sIconWidth / backWidth,
							(float) sIconHeight / backHeight);
					canvas.drawBitmap(Bitmap.createBitmap(backBitmap, 0, 0,
							backWidth, backHeight, matrix, true), 0.0f, 0.0f,
							null);
				} else {
					canvas.drawBitmap(backBitmap, 0.0f, 0.0f, null);
				}
			}*/
                        将应用图标bitmap绘制在画布上
			sOldBounds.set(icon.getBounds());
			icon.setBounds(left, top, left + width, top + height);
			icon.draw(canvas);
			icon.setBounds(sOldBounds);
			canvas.setBitmap(null);
                        //返回已经过处理的圆角bitmap
			return getRoundedBitmap(bitmap);
		}
	}

             下面是圆角处理函数

             

	//bitmap圆角处理
	public static Bitmap getRoundedBitmap(Bitmap mBitmap){
        //Bitmap mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.frame);  
        //创建与原始位图大小相同的画布位图ᄡᄡᄑᄄ￐ᅡ샤ᅫ콰ᄐ  
        Bitmap bgBitmap = Bitmap.createBitmap(mBitmap.getWidth(), mBitmap.getHeight(), Config.ARGB_8888);  
        //初始化画布
        Canvas mCanvas = new Canvas(bgBitmap);  
          
        Paint mPaint = new Paint();  
        Rect mRect = new Rect(0, 0, mBitmap.getWidth(), mBitmap.getHeight());  
        RectF mRectF = new RectF(mRect);  
        //设置圆角半径 
        float roundPx = 70;  
        mPaint.setAntiAlias(true);  
        //绘制圆角矩形
        mCanvas.drawRoundRect(mRectF, roundPx, roundPx, mPaint); 
          
        //设置图像的叠加模式, 此处模式选择可参考后面的规则
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        //绘制图像  
        mCanvas.drawBitmap(mBitmap, mRect, mRect, mPaint);  
          
        return bgBitmap;  
}

              1.PorterDuff.Mode.CLEAR
               所绘制不会提交到画布上。
              2.PorterDuff.Mode.SRC
               显示上层绘制图片
              3.PorterDuff.Mode.DST
               显示下层绘制图片
              4.PorterDuff.Mode.SRC_OVER
               正常绘制显示,上下层绘制叠盖。
              5.PorterDuff.Mode.DST_OVER
               上下层都显示。下层居上显示。
              6.PorterDuff.Mode.SRC_IN
               取两层绘制交集。显示上层。
              7.PorterDuff.Mode.DST_IN
               取两层绘制交集。显示下层。
              8.PorterDuff.Mode.SRC_OUT
               取上层绘制非交集部分。
              9.PorterDuff.Mode.DST_OUT
               取下层绘制非交集部分。
             10.PorterDuff.Mode.SRC_ATOP
               取下层非交集部分与上层交集部分
             11.PorterDuff.Mode.DST_ATOP
               取上层非交集部分与下层交集部分
             12.PorterDuff.Mode.XOR
             13.PorterDuff.Mode.DARKEN
             14.PorterDuff.Mode.LIGHTEN
             15.PorterDuff.Mode.MULTIPLY
             16.PorterDuff.Mode.SCREEN

          通过以上的代码就可以实现应用图标的圆角处理,效果可在修改后自行看到,在此不贴图了,每次截图甚是麻烦。同时对于位图的处理实际还可以有很多做法,可以参考来做,诸多效果在此借鉴下其他网友的做法

             带倒影的图标位图处理代码

           

	public static Bitmap createReflectionImageWithOrigin(Bitmap bitmap) {
		final int reflectionGap = 4;
		int w = bitmap.getWidth();
		int h = bitmap.getHeight();

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

		Bitmap reflectionImage = Bitmap.createBitmap(bitmap, 0, h / 2, w,
				h / 2, matrix, false);

		Bitmap bitmapWithReflection = Bitmap.createBitmap(w, (h + h / 2),
				Config.ARGB_8888);

		Canvas canvas = new Canvas(bitmapWithReflection);
		canvas.drawBitmap(bitmap, 0, 0, null);
		Paint deafalutPaint = new Paint();
		canvas.drawRect(0, h, w, h + reflectionGap, deafalutPaint);

		canvas.drawBitmap(reflectionImage, 0, h + reflectionGap, null);

		Paint paint = new Paint();
		LinearGradient shader = new LinearGradient(0, bitmap.getHeight(), 0,
				bitmapWithReflection.getHeight() + reflectionGap, 0x70ffffff,
				0x00ffffff, TileMode.CLAMP);
		paint.setShader(shader);
		// Set the Transfer mode to be porter duff and destination in
		paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
		// Draw a rectangle using the paint with our linear gradient
		canvas.drawRect(0, h, w, bitmapWithReflection.getHeight()
				+ reflectionGap, paint);

		return bitmapWithReflection;
	}
            还有直接可以缩放drawable对象的代码,这样可以不用刻意的获取drawable的bitmap对象位图再对位图进行缩放,再绘制去实现缩放的功能。

             

	public static Drawable zoomDrawable(Drawable drawable, int w, int h) {
		int width = drawable.getIntrinsicWidth();
		int height = drawable.getIntrinsicHeight();
		// drawable转换成bitmap
		Bitmap oldbmp = drawableToBitmap(drawable);
		// 创建操作图片用的Matrix对象
		Matrix matrix = new Matrix();
		// 计算缩放比例
		float sx = ((float) w / width);
		float sy = ((float) h / height);
		// 设置缩放比例
		matrix.postScale(sx, sy);
		// 建立新的bitmap,其内容是对原bitmap的缩放后的图
		Bitmap newbmp = Bitmap.createBitmap(oldbmp, 0, 0, width, height,
				matrix, true);
		return new BitmapDrawable(newbmp);
	}

             bitmap的缩放处理代码

             

	public static Bitmap zoomBitmap(Bitmap bitmap, int width, int height) {
		int w = bitmap.getWidth();
		int h = bitmap.getHeight();
		Matrix matrix = new Matrix();
		float scaleWidth = ((float) width / w);
		float scaleHeight = ((float) height / h);
		matrix.postScale(scaleWidth, scaleHeight);
		Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, w, h, matrix, true);
		return newbmp;
	}
         

             以上就是对于launcher2的图标处理方法的解析和修改。

你可能感兴趣的:(图片,android应用,位图,launcher2,图标加载流程)