配色: 字号:
Android绘制进阶
2013-05-08 | 阅:  转:  |  分享 
  
Android绘制进阶之一:图形的绘制

开始学习绘制,首先联系图像的基本元素的绘制,包括点线面及路径的绘制,没有难度,代码示例如下:

1.packagecom.mike.activity;

2.

3.importandroid.R;

4.importandroid.app.Activity;

5.importandroid.graphics.Bitmap;

6.importandroid.graphics.Canvas;

7.importandroid.graphics.Color;

8.importandroid.graphics.Paint;

9.importandroid.graphics.Paint.Style;

10.importandroid.graphics.Path;

11.importandroid.graphics.RectF;

12.importandroid.graphics.drawable.BitmapDrawable;

13.importandroid.os.Bundle;

14.importandroid.view.ViewGroup.LayoutParams;

15.importandroid.widget.ImageView;

16.importandroid.widget.LinearLayout;

17.

18.publicclassDrawDemoActivityextendsActivity{

19./Calledwhentheactivityisfirstcreated./

20.@Override

21.publicvoidonCreate(BundlesavedInstanceState){

22.super.onCreate(savedInstanceState);

23.

24./

25.配置類型:1,ALPHA_8:用于Alpha蒙版的位图,只为alpha通道分配8位,没有其他颜色

26.2,ARGB_4444,

27.3,ARGB_8888,

28.4,RGB565(与ARGB_8888具有相同的高质量,但占用更少的内存)

29.

30.ARGB_8888:每个颜色占8位,创建位图蓝盾在线http://www.parkshanghai.com

31.param:A:alpha通道:灰度通道,用来表明透明度信息,共256级

32.R:red

33.G:green

34.B:blue

35.

36.

37.Note:蒙板:蒙板要结合图层来使用。蒙板的用处很多,可以用来扣图、创建选区等等,

38.由于我好久不用PS了,所以蒙板的好多功能在这里不能一下子讲完。

39.举个通俗的例子:蒙板就是一块布,在某一图层上添加蒙板后就是在那个图层上盖了一块布,

40.利用那块布可以实现多种效果,用黑色在蒙板上填充就看不见蒙板所在图层下面的东西,

41.用白色填充就看见蒙板所在图层下面的东西,还可以利用蒙板制作渐变。

42.总之蒙板这个功能说复杂它就复杂,说它简单它就简单,这个家伙功能不小。

43.

44./

45.Bitmapbitmap=Bitmap.createBitmap(getWindowManager().getDefaultDisplay().getWidth(),

46.getWindowManager().getDefaultDisplay().getHeight(),

47.Bitmap.Config.ARGB_8888);//配置

48.

49.

50.

51.Canvascanvas=newCanvas(bitmap);//画布

52.

53.Paintpaint=newPaint();

54.paint.setColor(Color.WHITE);//可以直接设置颜色,也可通过Argb方法,,设置精确颜色

55.//intmyColor=Color.argb(alpha,red,green,blue);

56.

57.

58./

59.风格:

60.STROKE仅绘形状的轮廓

61.FILL仅填充形状

62.FILL_AND_STROKE填充并绘制形状的轮廓

63./

64.

65.//1:画一个点

66.//paint.setStyle(Style.STROKE);不涉及封闭图形,不写此属性ok~

67.//paint.setStrokeWidth(100);

68.//canvas.drawPoint(199,201,paint);

69.

70.

71.//2,画一条线

72.//paint.setStyle(Style.STROKE);不涉及封闭图形,不写此属性ok~

73.//paint.setStrokeWidth(10);

74.//canvas.drawLine(50,50,100,100,paint);

75.

76.//3,画一个矩形

77.//paint.setStyle(Style.FILL_AND_STROKE);

78.//paint.setStrokeWidth(10);

79.//canvas.drawRect(50,50,100,100,paint);//另外一种绘制矩形的方法是:传递一个RectF对象

80.

81.//4,画一个椭圆

82.//paint.setStyle(Style.STROKE);

83.//paint.setStrokeWidth(10);

84.//RectFoval=newRectF(10,10,400,200);//即矩形的内接圆

85.//canvas.drawOval(oval,paint);

86.

87.//5,画一个圆

88.//paint.setStyle(Style.STROKE);

89.//paint.setStrokeWidth(10);

90.//canvas.drawCircle(100,100,50,paint);

91.

92.//6,路径:通过路径Path对象

93.//paint.setStyle(Style.STROKE);

94.//paint.setStrokeWidth(10);

95.//Pathpath=newPath();

96.//path.moveTo(20,20);//起始点

97.//path.lineTo(30,30);

98.//path.lineTo(40,60);

99.//path.lineTo(70,100);

100.//canvas.drawPath(path,paint);

101.

102.ImageViewimageView=newImageView(this);

103.

104.LayoutParamsp=newLayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.FILL_PARENT);

105.imageView.setLayoutParams(p);

106.imageView.setBackgroundDrawable(newBitmapDrawable(bitmap));

107.

108.

109.setContentView(imageView);

110.

111.

112.}

113.}

Android绘制进阶之二:文本的绘制

文本的绘制。

字体有三种类型:1,内置基本字体2,通过基本字体和样式,创建新的Typeface3,引入外部的ttf文件。

示例代码如下:



1.packagecom.mike.activity;

2.

3.importandroid.R;

4.importandroid.app.Activity;

5.importandroid.graphics.Bitmap;

6.importandroid.graphics.Canvas;

7.importandroid.graphics.Color;

8.importandroid.graphics.Paint;

9.importandroid.graphics.Typeface;

10.importandroid.graphics.Paint.Style;

11.importandroid.graphics.Path;

12.importandroid.graphics.RectF;

13.importandroid.graphics.drawable.BitmapDrawable;

14.importandroid.os.Bundle;

15.importandroid.view.ViewGroup.LayoutParams;

16.importandroid.widget.ImageView;

17.importandroid.widget.LinearLayout;

18.

19.publicclassDrawDemoActivityextendsActivity{

20./Calledwhentheactivityisfirstcreated./

21.@Override

22.publicvoidonCreate(BundlesavedInstanceState){

23.super.onCreate(savedInstanceState);

24.

25./

26.配置類型:1,ALPHA_8:用于Alpha蒙版的位图,只为alpha通道分配8位,没有其他颜色

27.2,ARGB_4444,

28.3,ARGB_8888,

29.4,RGB565(与ARGB_8888具有相同的高质量,但占用更少的内存)

30.

31.ARGB_8888:每个颜色占8位,创建位图

32.param:A:alpha通道:灰度通道,用来表明透明度信息,共256级

33.R:red

34.G:green

35.B:blue

36.

37.

38.Note:蒙板:蒙板要结合图层来使用。蒙板的用处很多,可以用来扣图、创建选区等等,

39.由于我好久不用PS了,所以蒙板的好多功能在这里不能一下子讲完。

40.举个通俗的例子:蒙板就是一块布,在某一图层上添加蒙板后就是在那个图层上盖了一块布,

41.利用那块布可以实现多种效果,用黑色在蒙板上填充就看不见蒙板所在图层下面的东西,

42.用白色填充就看见蒙板所在图层下面的东西,还可以利用蒙板制作渐变。

43.总之蒙板这个功能说复杂它就复杂,说它简单它就简单,这个家伙功能不小。

44.

45./

46.

47.

48.

49./

50.1,内置字体:

51.

52.a,Typeface.MONOSPACE:等宽字代替,每个字母之间的间隔相等

53.b,Typeface.SANS_SERIF:无衬线

54.c,Typeface.SERIF:有衬线

55.d,Typeface.DEFAULT:=Typeface.SANS_SERIF

56.e,Typeface.DEFAULT_BOLD无衬线粗体

57.

58.

59.

60.2,字体样式由基本字体和样式create新的Typeface

61.a,Typeface.BOLD粗体

62.b,Typeface.ITALIC意大利体

63.c,Typeface.NORMAL普通

64.d,Typeface.BOLD_ITALIC粗意大利体

65.

66.3,外部字体,通过asset引入ttf文件

67./

68.

69.

70.

71.

72.

73.

74.Bitmapbitmap=Bitmap.createBitmap(getWindowManager().getDefaultDisplay().getWidth(),

75.getWindowManager().getDefaultDisplay().getHeight(),

76.Bitmap.Config.ARGB_8888);//配置

77.

78.Canvascanvas=newCanvas(bitmap);//画布

79.

80.Paintpaint=newPaint();

81.paint.setColor(Color.WHITE);//可以直接设置颜色,也可通过Argb方法,,设置精确颜色

82.//intmyColor=Color.argb(alpha,red,green,blue);

83.paint.setStrokeWidth(50);//设置此size并不改变TextSize

84.

85.//1,使用内置字体

86.paint.setTypeface(Typeface.DEFAULT);

87.//2,通过样式,创建字体

88.Typefacetypeface=Typeface.create(Typeface.DEFAULT,Typeface.ITALIC);

89.//3,通过外部文件创建字体

90.//Typeface.createFromAsset(getAssets(),"filename.ttf");

91.

92.paint.setTextSize(50);//Size优先级更高

93.//canvas.drawText("hello",100,100,paint);//普通的绘制文本

94.

95.

96./

97.按照指定路径画字

98./

99.Pathpath=newPath();

100.path.moveTo(10,10);

101.path.lineTo(50,50);

102.path.lineTo(150,250);

103.canvas.drawTextOnPath("hello",path,10,10,paint);

104.

105.

106.ImageViewimageView=newImageView(this);

107.

108.LayoutParamsp=newLayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.FILL_PARENT);

109.imageView.setLayoutParams(p);

110.imageView.setBackgroundDrawable(newBitmapDrawable(bitmap));

111.

112.setContentView(imageView);

113.

114.

115.}

116.}

Android绘制进阶之三:在位图上(Bitmap)绘制位图(Bitmap)

1,点击按钮,指定action和uri,设定结果码(ResultCode).到达手机默认相册的Gallery.



















代码如下:



1.publicvoidonClick(Viewv){

2.//TODOAuto-generatedmethodstub

3.Intentintent=newIntent(Intent.ACTION_PICK,

4.android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);//启动照片Gallery

5.startActivityForResult(intent,0);

6.}

2,选择图片,返回所选照片uri信息

代码如下:



1.@Override

2.protectedvoidonActivityResult(intrequestCode,intresultCode,Intentintent){

3.//TODOAuto-generatedmethodstub

4.super.onActivityResult(requestCode,resultCode,intent);

5.

6.if(resultCode==RESULT_OK){//操作成功

7.UriimgFileUri=intent.getData();//获得所选照片的信息



3,处理图片,设定合适的尺寸(正好适应屏幕)

设定BitmapFactory.Options参数inJustDecodeBounds=true,即不创建bitmap,但可获取bitmap的相关属性。以宽高比例差距最大者为基准。

代码如下:



1.//由于返回的图像可能太大而无法完全加载到内存中。系统有限制,需要处理。

2.DisplaycurrentDisplay=getWindowManager().getDefaultDisplay();

3.intdefaultHeight=currentDisplay.getHeight();

4.intdefaultWidth=currentDisplay.getWidth();

5.

6.BitmapFactory.OptionsbitmapFactoryOptions=newBitmapFactory.Options();

7.bitmapFactoryOptions.inJustDecodeBounds=true;///只是为获取原始图片的尺寸,而不返回Bitmap对象

8.//注上:Ifsettotrue,thedecoderwillreturnnull(nobitmap),buttheout...fieldswillstillbeset,

9.//allowingthecallertoquerythebitmapwithouthavingtoallocatethememoryforitspixels

10.try{

11.Bitmapbitmap=BitmapFactory.decodeStream(getContentResolver().openInputStream(imgFileUri),null,bitmapFactoryOptions);

12.intoutHeight=bitmapFactoryOptions.outHeight;

13.intoutWidth=bitmapFactoryOptions.outWidth;

14.intheightRatio=(int)Math.ceil((float)outHeight/defaultHeight);

15.intwidthRatio=(int)Math.ceil((float)outWidth/defaultWidth);

16.

17.if(heightRatio>1||widthRatio>1){

18.if(heightRatio>widthRatio){

19.bitmapFactoryOptions.inSampleSize=heightRatio;

20.}else{

21.bitmapFactoryOptions.inSampleSize=widthRatio;

22.}

23.}

4,inJustDecodeBounds=false,创建将此bitmap赋给第一个ImageView。

代码如下:



1.bitmapFactoryOptions.inJustDecodeBounds=false;

2.bitmap=BitmapFactory.decodeStream(getContentResolver().openInputStream(imgFileUri),null,bitmapFactoryOptions);

3.

4.mImageShow.setImageBitmap(bitmap);

5,绘制bitmap(选中的图片),赋给第二个ImageView

代码如下:



1./

2.在位图上绘制位图

3./

4.

5.BitmapbitmapAltered=Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(),bitmap.getConfig());

6.

7.Canvascanvas=newCanvas(bitmapAltered);//bitmap提供了画布,只在此提供了大小尺寸,偏移后并未有背景显示出来

8.

9.

10.Paintpaint=newPaint();

11.

12.canvas.drawBitmap(bitmap,0,0,paint);//绘制的图片和之前的一模一样

13.

14.mImageAltered.setImageBitmap(bitmapAltered);

Android绘制进阶之四:在位图上绘制文本并旋转

1,点击按钮,指定action和uri,设定结果码(ResultCode).到达手机默认相册的Gallery.























代码如下:



1.publicvoidonClick(Viewv){

2.//TODOAuto-generatedmethodstub

3.Intentintent=newIntent(Intent.ACTION_PICK,

4.android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);//启动照片Gallery

5.startActivityForResult(intent,0);

6.}

2,选择图片,返回所选照片uri信息

代码如下:



1.@Override

2.protectedvoidonActivityResult(intrequestCode,intresultCode,

3.Intentintent){

4.//TODOAuto-generatedmethodstub

5.super.onActivityResult(requestCode,resultCode,intent);

6.

7.if(resultCode==RESULT_OK){//操作成功

8.UriimgFileUri=intent.getData();//获得所选照片的信息

3,处理图片,设定合适的尺寸(正好适应屏幕)

设定BitmapFactory.Options参数inJustDecodeBounds=true,即不创建bitmap,但可获取bitmap的相关属性。以宽高比例差距最大者为基准。

代码如下:



1.//由于返回的图像可能太大而无法完全加载到内存中。系统有限制,需要处理。

2.DisplaycurrentDisplay=getWindowManager().getDefaultDisplay();

3.intdefaultHeight=currentDisplay.getHeight();

4.intdefaultWidth=currentDisplay.getWidth();

5.

6.BitmapFactory.OptionsbitmapFactoryOptions=newBitmapFactory.Options();

7.bitmapFactoryOptions.inJustDecodeBounds=true;///只是为获取原始图片的尺寸,而不返回Bitmap对象

8.//注上:Ifsettotrue,thedecoderwillreturnnull(nobitmap),but

9.//theout...fieldswillstillbeset,

10.//allowingthecallertoquerythebitmapwithouthavingto

11.//allocatethememoryforitspixels

12.try{

13.Bitmapbitmap=BitmapFactory.decodeStream(getContentResolver()

14..openInputStream(imgFileUri),null,

15.bitmapFactoryOptions);

16.intoutHeight=bitmapFactoryOptions.outHeight;

17.intoutWidth=bitmapFactoryOptions.outWidth;

18.intheightRatio=(int)Math.ceil((float)outHeight

19./defaultHeight);

20.intwidthRatio=(int)Math.ceil((float)outWidth

21./defaultWidth);

22.

23.if(heightRatio>1||widthRatio>1){

24.if(heightRatio>widthRatio){

25.bitmapFactoryOptions.inSampleSize=heightRatio;

26.}else{

27.bitmapFactoryOptions.inSampleSize=widthRatio;

28.}

29.}

4,inJustDecodeBounds=false,创建将此bitmap赋给第一个ImageView。

代码如下:



1.bitmapFactoryOptions.inJustDecodeBounds=false;

2.bitmap=BitmapFactory.decodeStream(getContentResolver()

3..openInputStream(imgFileUri),null,

4.bitmapFactoryOptions);

5.

6.mImageShow.setImageBitmap(bitmap);

5,绘制bitmap(选中的图片),赋给第二个ImageView

a,绘制正面Bitmap

b,在此Bitmap上绘制文本

c,创建Matrix对象,指定旋转角度。

d,创建新的bitmap对象,即canvas即将要绘制的倾斜区域

e,绘制

代码如下:



1.///

2.//在位图上绘制位图

3.///

4.//

5.

6.BitmapbitmapAltered=Bitmap.createBitmap(bitmap.getWidth(),

7.bitmap.getHeight(),bitmap.getConfig());

8.

9.Canvascanvas=newCanvas(bitmapAltered);//bitmap提供了画布,只在此提供了大小尺寸,偏移后并未有背景显示出来

10.

11.Paintpaint=newPaint();

12.

13.canvas.drawBitmap(bitmap,0,0,paint);

14.

15.paint.setColor(Color.RED);

16.

17.canvas.drawText("hello",10,10,paint);

18.

19.//先绘制正面图片,再旋转

20.Matrixmatrix=newMatrix();

21.

22.matrix.setRotate(45,0,0);

23.//创建一个倾斜的绘制区域

24.BitmapbitmapRotated=Bitmap.createBitmap(bitmapAltered,0,0,bitmapAltered.getWidth(),bitmapAltered.getHeight(),matrix,false);

25.canvas.drawBitmap(bitmapAltered,matrix,paint);

26.mImageAltered.setImageBitmap(bitmapRotated);

Android绘制进阶之五:位图的处理

图片的处理包括以下:

1,缩放

2,倾斜

3,旋转

4,缩放+

5,平移

6,镜像

代码如下:



1.packagecom.mike.activity;

2.

3.importjava.io.FileNotFoundException;

4.

5.importandroid.app.Activity;

6.importandroid.content.Intent;

7.importandroid.graphics.Bitmap;

8.importandroid.graphics.BitmapFactory;

9.importandroid.graphics.BitmapFactory.Options;

10.importandroid.graphics.Canvas;

11.importandroid.graphics.Color;

12.importandroid.graphics.Matrix;

13.importandroid.graphics.Paint;

14.importandroid.net.Uri;

15.importandroid.os.Bundle;

16.importandroid.util.Log;

17.importandroid.view.Display;

18.importandroid.view.View;

19.importandroid.view.View.OnClickListener;

20.importandroid.widget.Button;

21.importandroid.widget.ImageView;

22.

23.publicclassImageDemoActivityextendsActivityimplementsOnClickListener{

24./Calledwhentheactivityisfirstcreated./

25.

26.publicstaticStringTAG="IMAGE";

27.publicstaticintREQUEST_CODE=0;

28.privateImageViewmImageShow;

29.privateImageViewmImageAltered;

30.

31.@Override

32.publicvoidonCreate(BundlesavedInstanceState){

33.super.onCreate(savedInstanceState);

34.setContentView(R.layout.main);

35.

36.ButtonimageSelectBtn=(Button)findViewById(R.id.imageSelectBtn);

37.mImageShow=(ImageView)findViewById(R.id.imageShow);

38.mImageAltered=(ImageView)findViewById(R.id.imageAltered);

39.imageSelectBtn.setOnClickListener(this);

40.}

41.

42.publicvoidonClick(Viewv){

43.//TODOAuto-generatedmethodstub

44.Intentintent=newIntent(Intent.ACTION_PICK,

45.android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);//启动照片Gallery

46.startActivityForResult(intent,0);

47.}

48.

49.@Override

50.protectedvoidonActivityResult(intrequestCode,intresultCode,

51.Intentintent){

52.//TODOAuto-generatedmethodstub

53.super.onActivityResult(requestCode,resultCode,intent);

54.

55.if(resultCode==RESULT_OK){//操作成功

56.UriimgFileUri=intent.getData();//获得所选照片的信息

57.Log.d(TAG,"imgFileUriis:"+imgFileUri);

58.//由于返回的图像可能太大而无法完全加载到内存中。系统有限制,需要处理。

59.DisplaycurrentDisplay=getWindowManager().getDefaultDisplay();

60.intdefaultHeight=currentDisplay.getHeight();

61.intdefaultWidth=currentDisplay.getWidth();

62.

63.BitmapFactory.OptionsbitmapFactoryOptions=newBitmapFactory.Options();

64.bitmapFactoryOptions.inJustDecodeBounds=false;///只是为获取原始图片的尺寸,而不返回Bitmap对象

65.//注上:Ifsettotrue,thedecoderwillreturnnull(nobitmap),but

66.//theout...fieldswillstillbeset,

67.//allowingthecallertoquerythebitmapwithouthavingto

68.//allocatethememoryforitspixels

69.try{

70.Bitmapbitmap=BitmapFactory.decodeStream(getContentResolver()

71..openInputStream(imgFileUri),null,

72.bitmapFactoryOptions);

73.intoutHeight=bitmapFactoryOptions.outHeight;

74.intoutWidth=bitmapFactoryOptions.outWidth;

75.intheightRatio=(int)Math.ceil((float)outHeight

76./defaultHeight);

77.intwidthRatio=(int)Math.ceil((float)outWidth

78./defaultWidth);

79.

80.if(heightRatio>1||widthRatio>1){

81.if(heightRatio>widthRatio){

82.bitmapFactoryOptions.inSampleSize=heightRatio;

83.}else{

84.bitmapFactoryOptions.inSampleSize=widthRatio;

85.}

86.}

87.

88.bitmapFactoryOptions.inJustDecodeBounds=false;

89.bitmap=BitmapFactory.decodeStream(getContentResolver()

90..openInputStream(imgFileUri),null,

91.bitmapFactoryOptions);

92.

93.mImageShow.setImageBitmap(bitmap);

94.

95.///

96.//在位图上绘制位图

97.///

98.//

99.//BitmapbitmapAltered=Bitmap.createBitmap(bitmap.getWidth(),

100.//bitmap.getHeight(),bitmap.getConfig());

101.//

102.//Canvascanvas=new

103.//Canvas(bitmapAltered);//bitmap提供了画布,只在此提供了大小尺寸,偏移后并未有背景显示出来

104.//

105.//

106.//Paintpaint=newPaint();

107.//

108.//canvas.drawBitmap(bitmap,0,0,paint);//绘制的图片和之前的一模一样

109.//

110.//mImageAltered.setImageBitmap(bitmapAltered);

111.

112./

113.使用矩阵

114./

115.

116.BitmapbitmapAltered=Bitmap.createBitmap(bitmap.getWidth(),

117.bitmap.getHeight(),bitmap.getConfig());//缺点是限定画布大小,处理后的图片可能被截断,可引入矩阵构造方法,动态设定画布大小

118.Canvascanvas=newCanvas(bitmapAltered);//bitmap提供了画布,只在此提供了大小尺寸,偏移后并未有背景显示出来,

119.Paintpaint=newPaint();

120.

121.Matrixmatrix=newMatrix();

122.

123.//1:缩放

124.//matrix.setValues(newfloat[]{//涉及线性代数的知识,可以翻翻相乘的基础知识

125.//1,0,0,//算出x的值

126.//0,1,0,//算出y的值

127.//0,0,1//二维图用不到

128.//});

129.

130.//2:倾斜

131.//matrix.setValues(newfloat[]{//涉及线性代数的知识,可以翻翻相乘的基础知识

132.//1,.5f,0,//算出x的值,x,y值相关

133.//0,1,0,//算出y的值

134.//0,0,1//二维图用不到

135.//});

136.

137.//3:旋转

138.//matrix.setRotate(45);//设置旋转角度,(0,0)点,顺时针旋转45度

139.

140.//4,缩放plus:使用Matrix类方法//需要修改画布宽度>1.5倍原始宽度

141.//matrix.setScale(1.5f,1);

142.

143.//5,平移

144.//matrix.setTranslate(10,0);

145.

146.//6,镜像

147.//eg1:x轴镜像

148.//matrix.setScale(-1,1);//向左绘制,原始图片沿y轴对称

149.//matrix.postTranslate(bitmap.getWidth(),0);//注意是post即后移动

150.//eg2:y轴镜像

151.matrix.setScale(1,-1);//向上绘制,原始图片沿x轴对称,图像在第四象限

152.matrix.postTranslate(0,bitmap.getHeight());//注意是post即后移动

153.

154.

155.//~optimize~因为指定画布大小bitmapAltered,所以处理后的图片可能被截断,可以通过矩阵动态改变bitmapAltered大小

156.//eg:matrix.setRotate(degrees,px,py)

157.//bitmapAltered=Bitmap.createBitmap(source,x,y,width,height,m,filter);//显然矩阵影响其大小

158.

159.//

160.

161.//注:formoredetails:WikipediaTransformationMatrix

162.//http://en.wikipedia.org/wiki/Transformation_matrix

163.

164.canvas.drawBitmap(bitmap,matrix,paint);//绘制的图片和之前的一模一样

165.

166.mImageAltered.setImageBitmap(bitmapAltered);

167.

168.}catch(FileNotFoundExceptione){

169.//TODOAuto-generatedcatchblock

170.e.printStackTrace();

171.}

172.

173.}

174.}

175.}

Android绘制进阶之六:触摸轨迹的绘制及图片的保存

因为很多代码前面五次进阶已经设计,在此不赘述。单列出核心代码。

第一部分:xml文件

一个按钮选择图片,一个按钮保存图片

代码如下:

1.

2.
3.android:layout_width="fill_parent"

4.android:layout_height="fill_parent"

5.android:orientation="vertical">

6.

7.
8.android:id="@+id/pickImageBtn"

9.android:layout_width="wrap_content"

10.android:layout_height="wrap_content"

11.android:text="pickImage"/>

12.

13.
14.android:id="@+id/pickedImage"

15.android:layout_width="wrap_content"

16.android:layout_height="wrap_content"

17.android:src="@drawable/ic_launcher"/>

18.

19.
20.android:id="@+id/saveBtn"

21.android:layout_width="wrap_content"

22.android:layout_height="wrap_content"

23.android:text="Save"/>

24.

25.

第二部分:初始化

代码如下:

1.publicvoidonCreate(BundlesavedInstanceState){

2.super.onCreate(savedInstanceState);

3.setContentView(R.layout.main);

4.

5.ButtonpickImageBtn=(Button)findViewById(R.id.pickImageBtn);

6.ButtonsaveBtn=(Button)findViewById(R.id.saveBtn);

7.mImageView=(ImageView)findViewById(R.id.pickedImage);

8.

9.

10.pickImageBtn.setOnClickListener(this);

11.saveBtn.setOnClickListener(this);

12.

13.

14.}

第三部分:选择图片,监听Touch

代码如下:



1.publicvoidonClick(Viewv){

2.//TODOAuto-generatedmethodstub

3.Log.d("bitmap","hasonClick");

4.switch(v.getId()){

5.caseR.id.pickImageBtn:

6.Intentintent=newIntent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

7.startActivityForResult(intent,REQUEST_CODE);

8.break;



1.@Override

2.protectedvoidonActivityResult(intrequestCode,intresultCode,Intentintent){

3.//TODOAuto-generatedmethodstub

4.super.onActivityResult(requestCode,resultCode,intent);

5.Log.d("bitmap","requestCodeis:"+requestCode);

6.if(resultCode==RESULT_OK){

7.Log.d("bitmap","hasresultok");

8.Uriuri=intent.getData();

9.

10.intdw=getWindowManager().getDefaultDisplay().getWidth();

11.intdh=getWindowManager().getDefaultDisplay().getHeight();

12.

13.try{

14.BitmapFactory.Optionsopts=newBitmapFactory.Options();

15.opts.inJustDecodeBounds=true;//如果设置为true,本身不会返回

16.BitmapchooseBitmap=BitmapFactory.decodeStream(getContentResolver().openInputStream(uri),null,opts);

17.intbw=opts.outWidth;//此时,chooseBitmap的值为null,但opts仍然获得其config

18.intbh=opts.outHeight;

19.

20.intwidthRatio=(int)Math.ceil(bw/(float)dw);

21.intheightRatio=(int)Math.ceil(bh/(float)dh);

22.

23.if(widthRatio>1||heightRatio>1){

24.if(widthRatio>heightRatio){

25.opts.inSampleSize=widthRatio;//设置比例

26.}else{

27.opts.inSampleSize=heightRatio;

28.}

29.}

30.opts.inJustDecodeBounds=false;

31.chooseBitmap=BitmapFactory.decodeStream(getContentResolver().openInputStream(uri),null,opts);

32.Log.d("bitmap","chooseBitmapis:"+chooseBitmap);

33.

34.alteredBitmap=Bitmap.createBitmap(chooseBitmap.getWidth(),chooseBitmap.getHeight(),chooseBitmap.getConfig());

35.canvas=newCanvas(alteredBitmap);//画布

36.paint=newPaint();

37.paint.setColor(Color.WHITE);

38.paint.setStyle(Style.STROKE);

39.Matrixmatrix=newMatrix();

40.canvas.drawBitmap(chooseBitmap,matrix,paint);

41.

42.mImageView.setImageBitmap(alteredBitmap);

43.mImageView.setOnTouchListener(this);//设置监听

44.

45.}catch(FileNotFoundExceptione){

46.//TODOAuto-generatedcatchblock

47.e.printStackTrace();

48.}

49.

50.

51.

52.}

53.

54.}



第四部分:在图片上触摸移动,实时绘制。

代码如下:

1.publicbooleanonTouch(Viewv,MotionEventevent){

2.//TODOAuto-generatedmethodstub

3.Log.d("touch_draw","ontouch()");

4.

5.switch(event.getAction()){

6.caseMotionEvent.ACTION_UP:

7.//upX=event.getX();

8.//upY=event.getY();//画直线的相关代码,可自己测试。同理,画圆椭圆都可在相关方法里设置

9.//canvas.drawLine(downX,downY,upX,upY,paint);

10.//mImageView.invalidate();

11.//break;

12.caseMotionEvent.ACTION_DOWN:

13.downX=event.getX();

14.downY=event.getY();

15.break;

16.caseMotionEvent.ACTION_MOVE:

17.upX=event.getX();

18.upY=event.getY();

19.canvas.drawLine(downX,downY,upX,upY,paint);

20.mImageView.invalidate();

21.downX=upX;

22.downY=upY;

23.break;

24.caseMotionEvent.ACTION_CANCEL:

25.break;

26.

27.}

28.

29.returntrue;

30.}

第五部分:保存图片

代码如下:



1.publicvoidonClick(Viewv){

2.//TODOAuto-generatedmethodstub

3.Log.d("bitmap","hasonClick");

4.switch(v.getId()){

5.caseR.id.pickImageBtn:

6.Intentintent=newIntent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

7.startActivityForResult(intent,REQUEST_CODE);

8.break;

9.caseR.id.saveBtn://保存已经涂鸦过的图片

10.

11.

12./

13.PNG:非常适合艺术线条和图形:始终保持所有数据

14.JPEG:非常适合带渐变的全彩图像,例如照片。是“有损的”编解码器,可设置质量

15./

16.

17.

18.if(null!=alteredBitmap){

19.UriimageFileUri=getContentResolver().insert(Media.EXTERNAL_CONTENT_URI,newContentValues());//创建一个新的uri

20.

21.try{

22.OutputStreamimageFileOS=getContentResolver().openOutputStream(imageFileUri);//输出流

23.

24.alteredBitmap.compress(CompressFormat.JPEG,90,imageFileOS);//生成图片

25.

26.Toast.makeText(this,"hassaved",Toast.LENGTH_SHORT).show();

27.

28.}catch(FileNotFoundExceptione){

29.//TODOAuto-generatedcatchblock

30.e.printStackTrace();

31.}

32.}

33.break;

34.}

35.}







献花(0)
+1
(本文系糖糖啊首藏)