初学Android,图形图像之使用双缓冲画图(二十七)

xiaoxiao2021-02-27  355

当数据量很大时,绘图可能需要几秒钟甚至更长的时间,而且有时还会出现闪烁现象,为了解决这些问题,可采用双缓冲技术来绘图。  双缓冲即在内存中创建一个与屏幕绘图区域一致的对象,先将图形绘制到内存中的这个对象上,再一次性将这个对象上的图形拷贝到屏幕上,这样能大大加快绘图的速度。双缓冲实现过程如下:   1、在内存中创建与画布一致的缓冲区   2、在缓冲区画图   3、将缓冲区位图拷贝到当前画布上

  4、释放内存缓冲区

下面的例子(一个画图板)将实现双缓冲画图

先自定义一个View(Bitmap将会绘制到这个View上)

[java]  view plain  copy  print ? <span style="font-size:14px;">package Wangli.Graphics.HandDraw;   import android.content.Context;   import android.graphics.Bitmap;   import android.graphics.Bitmap.Config;   import android.graphics.Canvas;   import android.graphics.Color;   import android.graphics.Paint;   import android.graphics.Path;   import android.util.AttributeSet;   import android.view.MotionEvent;   import android.view.View;      public class DrawView extends View {       float preX;       float preY;       private Path path;       public Paint paint = null;       final int VIEW_WIDTH = 320;       final int VIEW_HEIGHT = 480;       //定义一个内存中的图片,该图片将作为缓冲区       Bitmap cacheBitmap = null;       //定义cacheBitmap上的canvas对象       Canvas cacheCanvas = null;       public DrawView(Context context, AttributeSet attrs) {           super(context, attrs);           //创建一个与该View相同大小的缓存区           cacheBitmap = Bitmap.createBitmap(VIEW_WIDTH,VIEW_HEIGHT,Config.ARGB_8888);           cacheCanvas = new Canvas();           path = new Path();           //设置cacheCanvas将会绘制到内存中的cacheBitmap上           cacheCanvas.setBitmap(cacheBitmap);           //设置画笔的颜色           paint = new Paint(Paint.DITHER_FLAG);           paint.setColor(Color.RED);           //设置画笔的风格           paint.setStyle(Paint.Style.STROKE);           paint.setStrokeWidth(1);           //反锯齿           paint.setAntiAlias(true);           paint.setDither(true);       }       public boolean onTouchEvent(MotionEvent event)       {           //获取拖动事件发生的位置           float x = event.getX();           float y = event.getY();           switch(event.getAction())           {               case MotionEvent.ACTION_DOWN:                    path.moveTo(x, y);                    preX = x;                    preY = y;                    break;               case MotionEvent.ACTION_MOVE:                    path.quadTo(preX, preY, x, y);                    preX = x;                    preY = y;                    break;               case MotionEvent.ACTION_UP:                    cacheCanvas.drawPath(path, paint);                    path.reset();                    break;           }           invalidate();           //返回true表明处理方法已经处理该事件           return true;       }       public void onDraw(Canvas canvas)       {           Paint bmpPaint = new Paint();           //将cacheBitmap绘制到该View组件上           canvas.drawBitmap(cacheBitmap, 00, bmpPaint);           //沿着path绘制           canvas.drawPath(path, paint);       }   }</span><span style="font-size:12px;">   </span>   定义菜单资源文件my_menu

[html]  view plain  copy  print ? <span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?>   <menu xmlns:android="http://schemas.android.com/apk/res/android">       <item android:title="@string/color">           <menu>               <!-- 定义一组单选菜单项 -->               <group android:checkableBehavior="single">                   <!-- 定义多个菜单项 -->                   <item                       android:id="@+id/red" android:title="@string/color_red"/>                   <item                       android:id="@+id/green" android:title="@string/color_green"/>                   <item                       android:id="@+id/blue" android:title="@string/color_blue"/>               </group>           </menu>       </item>       <item android:title="@string/width">           <menu>               <!-- 定义一组菜单项 -->               <group>                   <!-- 定义3个菜单项 -->                   <item                       android:id="@+id/width_1" android:title="@string/width_1"/>                   <item                       android:id="@+id/width_3" android:title="@string/width_3"/>                   <item                       android:id="@+id/width_5" android:title="@string/width_5"/>                                     </group>           </menu>       </item>       <item           android:id="@+id/blur" android:title="@string/blur"/>           <item           android:id="@+id/emboss" android:title="@string/emboss"/>                               </menu></span>   strings.xml

[html]  view plain  copy  print ? <?xml version="1.0" encoding="utf-8"?>   <resources>     <string name="hello">Hello World, HandDraw!</string>      <string name="app_name">手绘</string>      <string name="width_1">1像素</string>      <string name="width_3">3像素</string>      <string name="width_5">5像素</string>      <string name="color_red">红色</string>      <string name="color_green">绿色</string>      <string name="color_blue">蓝色</string>      <string name="color">画笔颜色</string>      <string name="width">画笔宽度</string>      <string name="blur">模糊效果</string>      <string name="emboss">浮雕效果</string>    </resources>   主界面处理菜单事件 

[java]  view plain  copy  print ? package Wangli.Graphics.HandDraw;      import android.app.Activity;   import android.graphics.BlurMaskFilter;   import android.graphics.Color;   import android.graphics.EmbossMaskFilter;   import android.os.Bundle;   import android.view.Menu;   import android.view.MenuInflater;   import android.view.MenuItem;      public class HandDraw extends Activity {       /** Called when the activity is first created. */       EmbossMaskFilter emboss;       BlurMaskFilter blur;       @Override       public void onCreate(Bundle savedInstanceState) {           super.onCreate(savedInstanceState);           setContentView(R.layout.main);           emboss = new EmbossMaskFilter(new float[]{1.5f,1.5f,1.5f},0.6f,6,4.2f);           blur = new BlurMaskFilter(8,BlurMaskFilter.Blur.NORMAL);       }       //负责创建选项菜单       public boolean onCreateOptionsMenu(Menu menu)       {           MenuInflater inflator = new MenuInflater(this);           //状态R.menu.context对应菜单,并添加到中           inflator.inflate(R.menu.my_menu,menu);           return super.onCreateOptionsMenu(menu);       }       //菜单项被单击后的回调方法       public boolean onOptionsItemSelected(MenuItem mi)       {           DrawView dv = (DrawView)findViewById(R.id.draw);           //判断单击的是哪个菜单项,并有针对性地做出响应           switch(mi.getItemId())           {               case R.id.red:                   dv.paint.setColor(Color.RED);                   mi.setChecked(true);                   break;               case R.id.green:                   dv.paint.setColor(Color.GREEN);                   mi.setChecked(true);                   break;               case R.id.blue:                   dv.paint.setColor(Color.BLUE);                   mi.setChecked(true);                   break;               case R.id.width_1:                   dv.paint.setStrokeWidth(1);                   mi.setChecked(true);                   break;               case R.id.width_3:                   dv.paint.setStrokeWidth(3);                   mi.setChecked(true);                   break;               case R.id.width_5:                   dv.paint.setStrokeWidth(5);                   mi.setChecked(true);                   break;               case R.id.blur:                   dv.paint.setMaskFilter(blur);                   mi.setChecked(true);                   break;               case R.id.emboss:                   dv.paint.setMaskFilter(emboss);                   mi.setChecked(true);                   break;           }           return true;       }   }   下面是实现效果

更改画笔效果

转载请注明原文地址: https://www.6miu.com/read-4536.html

最新回复(0)