Android有关图形图像的学习总结

来源:互联网 发布:淘宝个人简历模板 编辑:程序博客网 时间:2024/06/05 04:55

(一)图形操作

一、Android中的Path、Canvas、Paint的用法

1、Path

Path路径类在位于android.graphics.Path中,具体方法如下:

reset()方法:reset()清除path设置的所有属性

lineTo(float x, float y)方法:lineTo(float x, float y)方法用于从当前轮廓点绘制一条线段到x,y点:

moveTo(float x, float y)方法:path的moveTo方法将起始轮廓点移至x,y坐标点,默认情况为0,0点

close()方法:回到初始点形成封闭的曲线addArc(RectF oval, float startAngle, float sweepAngle)方法:path.addArc方法用于绘制圆

弧,这个圆弧取自RectF矩形的内接椭圆上的一部分,圆弧长度由后两个参数决定-startAngle:起始位置的角度值,sweepAngle:

旋转的角度值

arcTo(RectF oval, float startAngle, float sweepAngle)和addArc(RectF oval, float startAngle, float sweepAngle)方法区别:

     1. addArc可以直接加入一段椭圆弧。使用arcTo还需要使用moveTo指定当前点的坐标。

     2. arcTo如果当前点坐标和曲线的起始点不是同一个点的话,还会自动添加一条直线补齐路径。

addCircle(float x, float y, float radius, Direction dir)方法: 使用path绘制圆形,xy为圆的圆心 radius为圆的半径,Direction 为绘制元  的方向- Diection.CCW 逆时针方向,Diection.CW 顺时针方向

addOval(RectF oval, Path.Direction dir)方法:绘制椭圆,同上绘制圆的方法

addPath(Path src, float dx, float dy)方法: 在已有的Path上通过平移创建新的path。

       2、Canvas

Canvas类主要实现了屏幕的绘制过程,方法包含如绘制一条路径、区域、贴图、画点、画线、渲染文本。

常用方法如下:

void drawRect(RectF rect, Paint paint) //绘制区域,参数一为RectF区域

void drawPath(Path path, Paint paint) //绘制一个路径,参数一为Path路径对象

void  drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint)   //贴图,参数一是Bitmap对象,参数二是源区域(bitmap),参数三是目标区域(canvas

的位置和大小),参数四是Paint画刷对象,因为用到了缩放和拉伸的可能,当原始Rect不等于目标Rect时性能将会有大幅损失。

void  drawLine(float startX, float startY, float stopX, float stopY, Paint paint)  //画线,参数一起始点的x轴位置,参数二起始点的y轴位置,参数三终点

的x轴水平位置,参数四y轴垂直位置,最后一个参数为Paint画刷对象。

void  drawPoint(float x, float y, Paint paint) //画点,参数一水平x轴,参数二垂直y轴,第三个参数为Paint对象。

void drawText(String text, float x, float y, Paint paint)  //渲染文本,Canvas类除了上面的还可以描绘文字,参数一是String类型的文本,参数二x轴,参数三y轴,参数四是Paint对象。

void  drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) //在路径上绘制文本,相对于上面第二个参数是Path路径对像

Canvas绘制类简单灵活,形象的说明:如果把Canvas当做绘画师来看,那么Paint就是绘画的工具,比如画笔、画刷、颜料等等。

     3.Paint

 Paint类常用方法:

 void  setARGB(int a, int r, int g, int b)  设置Paint对象颜色,参数一为alpha透明通道

 void  setAlpha(int a)  设置alpha不透明度,范围为0~255

 void  setAntiAlias(boolean aa)  //是否抗锯齿

 void  setColor(int color)  //设置颜色,Android内部定义的有Color类包含了一些常见颜色定义

 void  setFakeBoldText(boolean fakeBoldText)  //设置为粗体文本

 void  setLinearText(boolean linearText)  //设置线性文本

 PathEffect  setPathEffect(PathEffect effect)  //设置路径效果

 Rasterizer  setRasterizer(Rasterizer rasterizer) //设置光栅化

 Shader  setShader(Shader shader)  //设置阴影

 void  setTextAlign(Paint.Align align)  //设置文本对齐

 void  setTextScaleX(float scaleX)  //设置文本缩放倍数,1.0f为原始

 void  setTextSize(float textSize)  //设置字体大小

 Typeface  setTypeface(Typeface typeface)  //设置字体,Typeface包含了字体的类型,粗细,还有倾斜、颜色等。

 void  setUnderlineText(boolean underlineText)  //设置下划线

 最终Canvas和Paint在onDraw中直接使用

示例代码:

实现绘制六种平面二维图形的三种不同表示以及文字的表示

图形的三种表示分别为:空心,实心,渐变。文字显示为渐变

 private class MyView extends View {        public MyView(Context context){            super(context);        }        /*        MyView继承View类,重写OnDraw方法,程序运行就会执行该方法,以Paint将几何图形绘制Canvas        上。         */        @Override        protected void onDraw(Canvas canvas){            super.onDraw(canvas);            canvas.drawColor(Color.WHITE);//设置背景为白色            Paint paint=new Paint();            paint.setAntiAlias(true);//去掉锯齿            paint.setColor(Color.BLUE);//为Paint设置为蓝色,绘制出的图形即为蓝色            paint.setStyle(Paint.Style.STROKE);//设置绘制出的图形为空心            paint.setStrokeWidth(6);//设置Paint的外框宽度            canvas.drawCircle(40,40,30,paint);//空心圆形            canvas.drawRect(10,90,70,150,paint);//空心正方形            canvas.drawRect(10,170,70,200,paint);//空心长方形            canvas.drawOval(new RectF(10,220,70,250),paint);//空心椭圆形            //空心的三角形            Path path=new Path();            path.moveTo(10,330);            path.lineTo(70,330);            path.lineTo(40,270);            path.close();            canvas.drawPath(path,paint);            //空心的梯形            Path path1=new Path();            path1.moveTo(10,410);            path1.lineTo(70,410);            path1.lineTo(55,350);            path1.lineTo(25,350);            path1.close();            canvas.drawPath(path1,paint);            //重新设置画笔的颜色为红色            paint.setColor(Color.RED);            paint.setStyle(Paint.Style.FILL);//实心图形            canvas.drawCircle(120,40,30,paint);//实心圆            canvas.drawRect(90,90,150,150,paint);//实心正方行            canvas.drawRect(90,170,150,200,paint);//实心长方形            canvas.drawOval(new RectF(90,220,150,250),paint);//实心椭圆            //实心三角形            Path path2=new Path();            path2.moveTo(90,330);            path2.lineTo(150,330);            path2.lineTo(120,270);            path2.close();            canvas.drawPath(path2,paint);            //实心梯形            Path path3=new Path();            path3.moveTo(90,410);            path3.lineTo(150,410);            path3.lineTo(135,350);            path3.lineTo(105,350);            path3.close();            canvas.drawPath(path3,paint);            //设置渐变色画笔            Shader mShader=new LinearGradient(0,0,100,100,new int[]{Color.RED,Color.GREEN,Color.BLUE,Color.YELLOW},null,Shader.TileMode.REPEAT);            paint.setShader(mShader);//用Shader中定义的颜色来画图形            canvas.drawCircle(200,40,30,paint);//渐变色圆            canvas.drawRect(170,90,230,150,paint);//渐变色正方形            canvas.drawRect(170,170,230,200,paint);//渐变色长方形            canvas.drawOval(new RectF(170,220,230,250),paint);//渐变色椭圆            //渐变色三角形            Path path4=new Path();            path4.moveTo(170,330);            path4.lineTo(230,330);            path4.lineTo(200,270);            path4.close();            canvas.drawPath(path4,paint);            //渐变色梯形            Path path5=new Path();            path5.moveTo(170,410);            path5.lineTo(230,410);            path5.lineTo(215,350);            path5.lineTo(185,350);            path5.close();            canvas.drawPath(path5,paint);            //实现写字功能。            paint.setTextSize(50);            canvas.drawText("圆形",240,50,paint);            canvas.drawText("正方形",240,120,paint);            canvas.drawText("长方形",240,190,paint);            canvas.drawText("椭圆形",240,250,paint);            canvas.drawText("三角形",240,320,paint);            canvas.drawText("梯形",240,390,paint);        }    }
显示效果:

      二、Android中Paint的PathEffect[]实现不同的路径效果

Android中共有六种路径效果

1、 effects[0]=null;不设置路径效果

2、 effects[1]=new CornerPathEffect(10);

      CornerPathEffect可以将路径的转角变得圆滑,CornerPathEffect的构造方法接受一个参数radius,即转角处的

      圆滑程度。

3.  effects[2]=new DiscretePathEffect(3.0f,5.0f);

     DiscretePathEffect(离散路径效果)会在路径上绘制很多“杂点”。其构造方法有两个参数:

     第一个参数指定这些突出的“杂点”的密度,值越小杂点越密集;

    第二个参数是“杂点”突出的大小,值越大突出的距离越大。

4、effects[3]=new DashPathEffect(new float[]{20,10,5,10},phase);

     包含了两个参数:

     第一个参数是一个浮点型的数组,定义该参数的时候只要浮点型数组中元素个数大于等于2即可。下标从0开 

     始,偶数下标代表实线长度,奇数下标代表虚线长度

    第二个参数(phase)称之为偏移值,动态改变其值会让路径产生动画的效果。

5、effects[4]=new PathDashPathEffect(p,12,phase, PathDashPathEffect.Style.ROTATE);

     PathDashPathEffect和DashPathEffect类似,不同的是PathDashPathEffect可以自己定义路径虚线的样式:如

     可以定义由一个个小圆点组成的虚线。

6、effects[5]=new ComposePathEffect(effects[2],effects[4]);

     可以用来组合两种路径效果,即把两种效果二合一。

     ComposePathEffect(PathEffect outerpe, PathEffect innerpe)会先将路径变成innerpe的效果,再去复合outerpe

     的路径效果,即:outerpe(innerpe(Path));

7、effects[6]=new SumPathEffect(effects[4],effects[3]);

     也可以用来组合两种路径效果,但他会把两种路径效果加起来再作用于路径。

示例代码

实现上述7种路径效果

public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(new MyView(this));    }    class MyView extends View {        float phase;        PathEffect[] effects=new PathEffect[7];        int[] colors;        private Paint paint;        Path path;        public MyView(Context context){            super(context);            paint=new Paint();            paint.setStyle(Paint.Style.STROKE);            paint.setStrokeWidth(4);            //创建并初始化path            path=new Path();            path.moveTo(0,0);            for(int i=1;i<=15;i++){                //生成15个点,随机生成他们的Y坐标,并将他们链接成一条Path                path.lineTo(i*20,(float)Math.random()*60);            }            //初始化7个颜色            colors=new int[]{Color.BLACK,Color.BLUE,Color.CYAN,Color.GREEN,Color.MAGENTA,Color.RED,Color.YELLOW};        }        @Override        protected void onDraw(Canvas canvas){            canvas.drawColor(Color.WHITE);//背景设置为白色            effects[0]=null;            effects[1]=new CornerPathEffect(10);//使用cornerpatheffect路径效果            effects[2]=new DiscretePathEffect(3.0f,5.0f);//初始化            effects[3]=new DashPathEffect(new float[]{20,10,5,10},phase);            Path p=new Path();            p.addRect(0,0,8,8,Path.Direction.CCW);            effects[4]=new PathDashPathEffect(p,12,phase, PathDashPathEffect.Style.ROTATE);            effects[5]=new ComposePathEffect(effects[2],effects[4]);            effects[6]=new SumPathEffect(effects[4],effects[3]);            canvas.translate(8,8);//将画布到移动到(8,8)处开始绘制颜色来绘制路径            //使用7种不同路径效果和7种不同的            for(int i=0;i

显示效果


     三、Android种Canvas的drawTextOnPath

Android的Canvas提供了一个drawTextOnPath(String text,Path path,float hOffset,float vOffset,Paint paint)方法,该方法可以沿着Path路径绘制文本,其中text指文本内容,hOffset参数指定水平偏移、vOffset指定垂直偏移.

示例代码

public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(new TextView(this));    }    class TextView extends View {        final String DRAW_STR="Android";        Path[]paths=new Path[3];        Paint paint;        public TextView(Context context){            super(context);            paths[0]=new Path();            paths[0].moveTo(0,0);            for(int i=1;i<=7;i++){                //生成7个点,随机生成他们的Y坐标,并将他们连接成一条path                paths[0].lineTo(i*30,(float)Math.random()*30);            }            paths[1]=new Path();            RectF rectF=new RectF(0,0,500,300);            paths[1].addOval(rectF, Path.Direction.CCW);            paths[2]=new Path();            paths[2].addArc(rectF,100,100);            paint=new Paint();//初始化画笔            paint.setAntiAlias(true);            paint.setColor(Color.RED);            paint.setStrokeWidth(1);        }        @Override        protected void onDraw(Canvas canvas){            canvas.drawColor(Color.WHITE);            canvas.translate(40,40);            paint.setTextAlign(Paint.Align.RIGHT);//设置从右边开始绘制,即右对齐            paint.setTextSize(40);            //绘制路径            paint.setStyle(Paint.Style.STROKE);            canvas.drawPath(paths[0],paint);            //沿着路径绘制一段文本            paint.setStyle(Paint.Style.FILL);            canvas.drawTextOnPath(DRAW_STR,paths[0],-8,20,paint);            //画布下移60            canvas.translate(0,60);            paint.setStyle(Paint.Style.STROKE);            //绘制路径            canvas.drawPath(paths[1],paint);            paint.setStyle(Paint.Style.FILL);            //沿着路径绘制一段文本            canvas.drawTextOnPath(DRAW_STR,paths[1],-20,20,paint);            //画布下移120            canvas.translate(0,120);            //绘制路径            paint.setStyle(Paint.Style.STROKE);            canvas.drawPath(paths[2],paint);            //沿着路径绘制一段文本            paint.setStyle(Paint.Style.FILL);            canvas.drawTextOnPath(DRAW_STR,paths[2],-10,20,paint);        }    }}

效果显示


    (二)图像操作

      一、图像列表

通过SimpleAdapter类实现图像列表

SimpleAdapter()包含五个参数

Context context:上下文(当前的Activity)

List<? extends Map<String, ?>> data:一个嵌套Map集合类型的list集合数据源

int resource:表示界面布局的id  表示该文件作为列表项的组件

String[] from:表示该Map对象的哪些key对应value来生成列表项

int[] to:表示来填充的组件 Map对象key对应的资源一依次填充组件 顺序有对应关系。

示例代码

public class MainActivity extends Activity {    private String []name={"卡通1","卡通2","卡通3","卡通4","卡通5"};    private String []desc={"吉祥如意","机灵活泼,通人性","可爱","侦探形象","浑身惊人的力气"};    private int [] imageids={R.drawable.kt1,R.drawable.kt2,R.drawable.po1,R.drawable.po2,R.drawable.po3};    private ListView lt1;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        List> listems=new ArrayList>();        for(int i=0;ilistem=new HashMap();            listem.put("head",imageids[i]);            listem.put("name",name[i]);            listem.put("desc",desc[i]);            listems.add(listem);        }         /*        simpleAdapter中的第一个参数为访问整个android应用程序的接口,第二个参数是生成一个Map(String,Object)列表,        第三个参数是布局界面的资源,第四个参数是该map对象哪些关键字对应value生成列表项,第五个参数是与第四个参数中的关键字对应的value资源,        顺序要对应。         */        SimpleAdapter simpleAdapter=new SimpleAdapter(this,listems,R.layout.listview_n,                new String[]{"name","head","desc"},new int[]{R.id.name,R.id.head,R.id.desc});        lt1=(ListView)findViewById(R.id.lt1);        lt1.setAdapter(simpleAdapter);    }}
显示效果


     二、图像的放大与缩小

在android开发中,bitmap用于图像处理。用它可以获取图像文件信息,进行图像剪切、旋转、缩放等操作,并可以指定格式保存图像文件。

获取Bitmap的方式

利用BitmapFactory可以从一个指定文件中,通过decodeFile()解出Bitmap;

也可以定义的图片资源中,利用decodeResource()解出Bitmap

本项目读取drawable中的图像通过如下语句实现

Bitmap  bitmap = BitmapFactory.decodeResource(this.getContext().getResources(), R.drawable.test);

示例代码

 smallButton.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                bmp=scaleToFit(bmp,0.6f);//单击缩小按钮,图像缩小到原来的60%                iv.setImageBitmap(bmp);            }        });        bigButton.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                bmp=scaleToFit(bmp,1.5f);//单击放大按钮,图像放大到原来的150%                iv.setImageBitmap(bmp);            }        });  public static Bitmap scaleToFit(Bitmap bm,float scale){       Bitmap bmResult=null;       int width =bm.getWidth();//图片宽度       int height=bm.getHeight();//图片高度       Matrix matrix =new Matrix();//创建矩阵       matrix.postScale(scale,scale);//图片等比例缩小       bmResult=Bitmap.createBitmap(bm,0,0,width,height,matrix,true);//声明位图        return  bmResult;    }     

显示效果
初始界面

点击变小按钮显示

在当前基础上点击变大按钮显示


    二、图像的动画效果滑动

通过TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta) 实现平移动画效果

参数含义
float fromXDelta 动画开始的点离当前View X坐标上的差值
float toXDelta 动画结束的点离当前View X坐标上的差值
float fromYDelta 动画开始的点离当前View Y坐标上的差值
float toYDelta 动画开始的点离当前View Y坐标上的差值

常用方法

animation.setDuration(long durationMillis);//设置动画持续时间
animation.setRepeatCount(int i);//设置重复次数
animation.setRepeatMode(Animation.REVERSE);//设置反方向执行

示例代码

 final TranslateAnimation animation=new TranslateAnimation(0,150,0,0);        animation.setDuration(2000);//设置动画持续的时间        animation.setRepeatCount(2);//设置重复的次数        animation.setRepeatMode(Animation.REVERSE);//设置可反方向执行  start.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                iv.startAnimation(animation);//开始动画            }        });        end.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                animation.cancel();//结束动画            }        });

显示效果
当点击开始按钮时,图像按预设的方式平行移动

    三、图像的淡入淡出实现

在主界面下点击“图像淡入淡出”,即创建一个新的Activity用于实现图像的逐渐消失与逐渐显示

通过如下语句实现

startView=new StartView(this);
this.setContentView(startView);

淡入淡出实现的核心技术:Surface

SurfaceView是View的继承类,可以控制Surface的格式和尺寸,并且通过SurfaceHolder接口访问surface,getHolder()方法可以得到这个接口。

1)实现

首先继承SurfaceView并实现SurfaceHolder.Callback接口
使用接口的原因:使用SurfaceView 有一个原则,所有的绘图工作必须在Surface 被创建之后才能开始(Surface—表面,在Surface 被销毁之前必须结束。所以Callback 中的surfaceCreated 和surfaceDestroyed 就成了绘图处理代码的边界。

2)整个过程

继承SurfaceView并实现SurfaceHolder.Callback接口 ----> SurfaceView.getHolder()获得SurfaceHolder对象 ---->SurfaceHolder.addCallback(callback)添加回调函数---->SurfaceHolder.lockCanvas()获得Canvas对象并锁定画布----> Canvas绘画 ---->SurfaceHolder.unlockCanvasAndPost(Canvas canvas)结束锁定画图,并提交改变,将图形显示。

示例代码

主界面有关图像淡入淡出操作的代码

  Alpha=(Button)findViewById(R.id.alpha_button) ;        Alpha.setOnClickListener(new OnClickListener() {//当点击图像淡入淡出时开启一个新的界面            @Override            public void onClick(View v) {                startview();            }        }); public void startview(){        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);        DisplayMetrics dm=new DisplayMetrics();//创建矩阵        getWindowManager().getDefaultDisplay().getMetrics(dm);        screenHeight=dm.heightPixels;//得到屏幕的高度        screenWeight=dm.widthPixels;//得到屏幕的宽度        startView=new StartView(this);        this.setContentView(startView);    }
自定义Activity实现淡入淡出功能的代码

public class StartView extends SurfaceView implements SurfaceHolder.Callback {//实现声明周期的回调接口    MainActivity activity;    Paint paint;    int currentAloha=0;//当前的透明度    int screenWidth=(int)MainActivity.screenWeight;    int screenHeight=(int)MainActivity.screenHeight;    int sleepSpan=50;    Bitmap[]logos=new Bitmap[2];    int pic1;    int pic2;    Bitmap currentLogo;//当前图片    int currentX;    int currentY;    public StartView(MainActivity activity){        super(activity);        this.activity=activity;        this.getHolder().addCallback(this);//生命周期回调接口的实现者为当前对象        paint=new Paint();//创建画笔        paint.setAntiAlias(true);//打开抗锯齿        pic1=R.drawable.kt1;        pic2=R.drawable.kt2;        logos[0]= BitmapFactory.decodeResource(activity.getResources(),pic1);//获取图片资源        logos[1]= BitmapFactory.decodeResource(activity.getResources(),pic2);        int bit_width = logos[0].getWidth();        int bit_height = logos[0].getHeight();        float p = (float) bit_height/bit_width;        //使图片设置为适合屏幕尺寸的大小,宽度为手机屏幕宽度,高度等比例变化        logos[0]= Bitmap.createScaledBitmap(logos[0], screenWidth,(int)(screenWidth*p), true);        int bit_width1 = logos[1].getWidth();        int bit_height1 = logos[1].getHeight();        float p1 = (float) bit_height1/bit_width1;        logos[1]= Bitmap.createScaledBitmap(logos[1], screenWidth,(int)(screenWidth*p1), true);    }    @Override    public void onDraw(Canvas canvas){        try {            //绘制白色填充矩形的背景            paint.setColor(Color.WHITE);            paint.setAlpha(255);            canvas.drawRect(0,0,screenWidth,screenHeight,paint);            if(currentLogo==null)return;            paint.setAlpha(currentAloha);            canvas.drawBitmap(currentLogo,0,0,paint);//设置图片        }        catch (Exception e){            e.printStackTrace();        }    }    public void surfaceCreated(SurfaceHolder arg0){//创建时就被调用        new Thread(){            @SuppressLint("WrongCall")            public void run(){                for(Bitmap bm:logos){                    currentLogo=bm;                    //图片位置                    currentX=screenWidth/2-bm.getWidth()/2;     //X坐标                    currentY=screenHeight/2-bm.getHeight()/2;       //Y坐标                    currentX=0;                    currentY=0;                    for(int i=255;i>-10;i=i-10){                        currentAloha=i;                        if(currentAloha<0){                            currentAloha=0;                        }                        SurfaceHolder myholder=StartView.this.getHolder();                        Canvas canvas=myholder.lockCanvas();  //获取画布                        try {                            synchronized (myholder){                                onDraw(canvas);         //开始绘制                            }                        }                        finally {                            if(canvas!=null){                                myholder.unlockCanvasAndPost(canvas);                            }                        }                        try {                            if(i==255){                                Thread.sleep(1000);                            }                            Thread.sleep(sleepSpan);                        }catch (Exception e){                            e.printStackTrace();                        }                    }                }            }        }.start();    }    @Override    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {    }    @Override    public void surfaceDestroyed(SurfaceHolder holder) {   //销毁时被调用,必须重构该函数    }}
显示效果

单点击在上述一或二实现的主界面中的“图像淡入淡出”按钮时,显示效果图如下:


注:上述(二)图像操作部分下的一、二、三小结是属于一个项目实现的








0 0
原创粉丝点击