位图是我们开发中最常用的资源,毕竟一个漂亮的界面对用户是最有吸引力的。

1. 从资源中获取位图

可以使用BitmapDrawable或者BitmapFactory来获取资源中的位图。

当然,首先需要获取资源:

Resources res=getResources();

使用BitmapDrawable获取位图

  1. 使用BitmapDrawable (InputStream is)构造一个BitmapDrawable;
  2. 使用BitmapDrawable类的getBitmap()获取得到位图;
// 读取InputStream并得到位图InputStream is=res.openRawResource(R.drawable.pic180);BitmapDrawable bmpDraw=new BitmapDrawable(is);Bitmap bmp=bmpDraw.getBitmap();

或者采用下面的方式:

BitmapDrawable bmpDraw=(BitmapDrawable)res.getDrawable(R.drawable.pic180);Bitmap bmp=bmpDraw.getBitmap();

使用BitmapFactory获取位图

(Creates Bitmap objects from various sources, including files, streams, and byte-arrays.)

使用BitmapFactory类decodeStream(InputStream is)解码位图资源,获取位图。

Bitmap bmp=BitmapFactory.decodeResource(res, R.drawable.pic180);

BitmapFactory的所有函数都是static,这个辅助类可以通过资源ID、路径、文件、数据流等方式来获取位图。

以上方法在编程的时候可以自由选择,在Android SDK中说明可以支持的图片格式如下:png (preferred), jpg (acceptable), gif (discouraged),和bmp(Android SDK Support Media Format)。

2. 获取位图的信息

要获取位图信息,比如位图大小、像素、density、透明度、颜色格式等,获取得到Bitmap就迎刃而解了,这些信息在Bitmap的手册中,这里只是辅助说明以下2点:

  • 在Bitmap中对RGB颜色格式使用Bitmap.Config定义,仅包括ALPHA_8、ARGB_4444、ARGB_8888、RGB_565,缺少了一些其他的,比如说RGB_555,在开发中可能需要注意这个小问题;
  • Bitmap还提供了compress()接口来压缩图片,不过AndroidSAK只支持PNG、JPG格式的压缩;其他格式的需要Android开发人员自己补充了。
3. 显示位图

显示位图可以使用核心类Canvas,通过Canvas类的drawBirmap()显示位图,或者借助于BitmapDrawable来将Bitmap绘制到Canvas。当然,也可以通过BitmapDrawable将位图显示到View中。

转换为BitmapDrawable对象显示位图

// 获取位图
Bitmap bmp=BitmapFactory.decodeResource(res, R.drawable.pic180);
// 转换为BitmapDrawable对象
BitmapDrawable bmpDraw=newBitmapDrawable(bmp);
// 显示位图
ImageView iv2 = (ImageView)findViewById(R.id.ImageView02);
iv2.setImageDrawable(bmpDraw);

使用Canvas类显示位图

这儿采用一个继承自View的子类Panel,在子类的OnDraw中显示

 1 public class MainActivity extends Activity { 2     /** Called when the activity is first created. */ 3     @Override 4     public void onCreate(Bundle savedInstanceState) { 5         super.onCreate(savedInstanceState); 6         setContentView(new Panel(this)); 7     } 8      9     class Panel extends View{           10         public Panel(Context context) {  11             super(context); 12         }      13         public void onDraw(Canvas canvas){  14             Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.pic180);  15             canvas.drawColor(Color.BLACK);  16             canvas.drawBitmap(bmp, 10, 10, null);  17         }  18     } 19 }


4. 位图缩放

(1)将一个位图按照需求重画一遍,画后的位图就是我们需要的了,与位图的显示几乎一样:drawBitmap(Bitmapbitmap,Rectsrc,Rectdst,Paintpaint)。

(2)在原有位图的基础上,缩放原位图,创建一个新的位图:CreateBitmap(Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter)

(3)借助Canvas的scale(float sx, float sy) (Preconcat the current matrix with the specified scale.),不过要注意此时整个画布都缩放了。

(4)借助Matrix:

Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.pic180);              Matrix matrix=new Matrix();            matrix.postScale(0.2f, 0.2f);            Bitmap dstbmp=Bitmap.createBitmap(bmp,0,0,bmp.getWidth(),            bmp.getHeight(),matrix,true);            canvas.drawColor(Color.BLACK);              canvas.drawBitmap(dstbmp, 10, 10, null); 
      
5. 位图旋转

同样,位图的旋转也可以借助Matrix或者Canvas来实现。

       Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.pic180);              Matrix matrix=new Matrix();            matrix.postScale(0.8f, 0.8f);            matrix.postRotate(45);            Bitmap dstbmp=Bitmap.createBitmap(bmp,0,0,bmp.getWidth(),            bmp.getHeight(),matrix,true);            canvas.drawColor(Color.BLACK);             canvas.drawBitmap(dstbmp, 10, 10, null); 
      

旋转效果:

6.图片水印的生成方法

生成水印的过程。其实分为三个环节:第一,载入原始图片;第二,载入水印图片;第三,保存新的图片。

  • /**
  • * create thebitmapfrom a byte array
  • *
  • * @param src thebitmapobject you want proecss
  • * @param watermark the water mark above the src
  • * @return return abitmapobject ,if paramter's length is 0,return null
  • */
  • privateBitmap createBitmap( Bitmap src, Bitmap watermark )
  • {
  • String tag ="createBitmap";
  • Log.d( tag,"create a newbitmap");
  • if( src ==null)
  • {
  • returnnull;
  • }
  • intw = src.getWidth();
  • inth = src.getHeight();
  • intww = watermark.getWidth();
  • intwh = watermark.getHeight();
  • //create the new blankbitmap
  • Bitmap newb = Bitmap.createBitmap( w, h, Config.ARGB_8888 );//创建一个新的和SRC长度宽度一样的位图
  • Canvas cv =newCanvas( newb );
  • //draw src into
  • cv.drawBitmap( src,0,0,null);//在 0,0坐标开始画入src
  • //draw watermark into
  • cv.drawBitmap( watermark, w - ww +5, h - wh +5,null);//在src的右下角画入水印
  • //save all clip
  • cv.save( Canvas.ALL_SAVE_FLAG );//保存
  • //store
  • cv.restore();//存储
  • returnnewb;
  • }

7.Canvas的save和restore

onDraw方法会传入一个Canvas对象,它是你用来绘制控件视觉界面的画布。

在onDraw方法里,我们经常会看到调用save和restore方法,它们到底是干什么用的呢?

❑ save:用来保存Canvas的状态。save之后,可以调用Canvas的平移、放缩、旋转、错切、裁剪等操作。

❑ restore:用来恢复Canvas之前保存的状态。防止save后对Canvas执行的操作对后续的绘制有影响。

save和restore要配对使用(restore可以比save少,但不能多),如果restore调用次数比save多,会引发Error。save和restore之间,往往夹杂的是对Canvas的特殊操作。

例如:我们先想在画布上绘制一个右向的三角箭头,当然,我们可以直接绘制,另外,我们也可以先把画布旋转90°,画一个向上的箭头,然后再旋转回来(这种旋转操作对于画圆周上的标记非常有用)。然后,我们想在右下角有个20像素的圆,那么,onDraw中的核心代码是:

int px = getMeasuredWidth();

int py = getMeasuredWidth();

// Draw background

canvas.drawRect(0, 0, px, py, backgroundPaint);

canvas.save();

canvas.rotate(90, px/2, py/2);

// Draw up arrow

canvas.drawLine(px / 2, 0, 0, py / 2, linePaint);

canvas.drawLine(px / 2, 0, px, py / 2, linePaint);

canvas.drawLine(px / 2, 0, px / 2, py, linePaint);

canvas.restore();

// Draw circle

canvas.drawCircle(px - 10, py - 10, 10, linePaint);

效果如图1所示:

如果我们不调用save和restore会是什么样子呢?如图2所示:

从这两个图中,我们就能看到圆圈位置的明显差异。不进行Canvas的save和restore操作的话,所有的图像都是在画布旋转90°后的画布上绘制的。当执行完onDraw方法,系统自动将画布恢复回来。save和restore操作执行的时机不同,就能造成绘制的图形不同。

本文参考: Android SDK

moandroid.com

http://www.cnblogs.com/xirihanlin/archive/2009/07/24/1530246.html

更多相关文章

  1. Android(安卓)地理编码&逆地理编码(百度、阿里接口对比)
  2. android java file 清理垃圾获取文件大小 删除文件等操作
  3. 通过adb shell dumpsys命令获取当前应用的component
  4. bt开发类
  5. uni-app之APP和小程序微信授权方法
  6. android adb root方法
  7. android webview中使用Java调用JavaScript方法并获取返回值
  8. android view setTag()和findViewWithTag()
  9. android wifi讲解 wifi列表显示

随机推荐

  1. android IntentService的深入理解
  2. Android中Spinner的用法
  3. android ndk 开发
  4. Android(安卓)studio SDK6.0 不支持HttpC
  5. Android(安卓)Signing your Applications
  6. 模拟android访问服务器
  7. Android:EditText插入图片实现图文混排
  8. Android(安卓)进程级别 和 oom_adj对应关
  9. Android(安卓)Untold Stories
  10. 解读ContentResolver和ContentProvider