欢迎来到 安卓源码空间!
安卓源码空间

       Android的图形处理:图片读存,缩转移,Shape图形,Selector多状态图,9patch图,自定义图形



简介


何为Graphics

手机上显示的任何界面, 无论是文字,按钮或图片, 都是系统内置的一些API绘制的Graphics(图形,图像)Graphics分为2D和3D两种在我们应用中操作最多的Graphics就是图片
用它我们要会:	如何操作图片	如何利用系统的相关API绘制一个自定义的Graphics

API

Bitmap:   		位图,图片在内存中数据对象  .bmp .jpg .png
Drawable: 		就是一个可画的对象,其可能是一张位图(BitmapDrawable),   也可能是一个图形(ShapeDrawable),有可能是一个图层(LayerDrawable)
		        我们根据画图的需求,创建相应的可画对象
Canvas: 		画布,手机屏幕上用于绘图的目标区域
Paint: 		        我们可以把它看做一个画图工具,比如画笔、画刷。 他管理了每个画图工具的字体、颜色、样式。
Matrix: 		矩阵,高等数学里有介绍,在图像处理方面,主要是用于平面的缩放、平移、旋转等操作

实践

图片的读取保存

用到的API	
	      加载图片得到bitmap对象BitmapFactory.decodeResource(Resources res, int id)BitmapFactory.decodeFile(String pathName)
	将bitmap对象保存到SD卡   compress(CompressFormat format, int quality, OutputStream stream)
package com.jane.graphics;

import java.io.FileNotFoundException;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

/*
 Bitmap: 加载一张图片数据到内存中, 都可以封装成一个Bitmap对象
 需求1: 加载资源文件中的图片资源并显示
 需求2: 加载存储空间中的图片资源并显示
 需求3: 将一个bitmap对象保存到存储空间中
 */
public class BitmapTestActivity extends Activity
{

	private ImageView iv_bitmap1;
	private ImageView iv_bitmap2;

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_bitmap);

		iv_bitmap1 = (ImageView) findViewById(R.id.iv_bitmap1);
		iv_bitmap2 = (ImageView) findViewById(R.id.iv_bitmap2);

		// 需求1: 加载资源文件中的图片资源并显示
		iv_bitmap1.setImageResource(R.drawable.ic_launcher);

		// 需求2: 加载存储空间中的图片资源并显示
		Bitmap bitmap = BitmapFactory.decodeFile("/storage/sdcard/ic_launcher.png");
		iv_bitmap2.setImageBitmap(bitmap);
	}

	public void saveImage(View v) throws FileNotFoundException
	{
		// 需求3: 将一个bitmap对象保存到存储空间中
		Bitmap bitmap = BitmapFactory.decodeFile("/storage/sdcard/ic_launcher.png");
		bitmap.compress(CompressFormat.PNG, 100,openFileOutput("ic_launcher.png", Context.MODE_PRIVATE));
		Toast.makeText(this, "保存完成", 0).show();
	}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="保存图片" 
        android:onClick="saveImage"/>

    <ImageView
        android:id="@+id/iv_bitmap1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

    <ImageView
        android:id="@+id/iv_bitmap2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

图片的缩放/旋转/平移处理

用的的API

在Android中, 可以通过Matrix来对图片进行缩放,旋转和平移的操作
Matrix: 矩阵(高数), 在图像处理方面,主要是用于平面的缩放、平移、旋转等操作
相关API:
		Matrix.postScale(float sx, float sy) : 缩放
		Matrix.postRotate(float degrees) : 旋转
		Matrix.postTranslate(float dx, float dy) : 平移
		Matrix.reset() : 清空重置

	ImageView.setImageMatrix(Matrix matrix) 设置图片的Matrix
package com.jane.graphics;

import android.app.Activity;
import android.graphics.Matrix;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;

public class MatrixTestActivity extends Activity
{

	private EditText et_matrix_scale;
	private EditText et_matrix_rotate;
	private EditText et_matrix_translateX;// 偏移量X
	private EditText et_matrix_translateY;// 偏移量Y

	private ImageView iv_matrix_icon;

	private Matrix matrix;

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_matrix);

		et_matrix_scale = (EditText) findViewById(R.id.et_matrix_scale);
		et_matrix_rotate = (EditText) findViewById(R.id.et_matrix_rotate);
		et_matrix_translateX = (EditText) findViewById(R.id.et_matrix_translateX);
		et_matrix_translateY = (EditText) findViewById(R.id.et_matrix_translateY);
		iv_matrix_icon = (ImageView) findViewById(R.id.iv_matrix_icon);
		matrix = new Matrix();
	}

	public void scaleBitmap(View view)
	{
		float scale = Float.parseFloat(et_matrix_scale.getText().toString());
		// 保存缩放比例
		matrix.postScale(scale, scale);
		// 将matrix设置到imageView
		iv_matrix_icon.setImageMatrix(matrix);
		/*
		 * 要想上面的Matrix起效果,就得在布局文件里面的图片视图里面进行设置:
		 * android:scaleType="matrix"
		 */
	}

	public void rotateBitmap(View view)
	{
		float degree = Float.parseFloat(et_matrix_rotate.getText().toString());
		// 保存旋转角度
		matrix.postRotate(degree);
		// 将matrix设置到imageView
		iv_matrix_icon.setImageMatrix(matrix);
	}

	public void translateBitmap(View view)
	{
		float dx = Float.parseFloat(et_matrix_translateX.getText().toString());
		float dy = Float.parseFloat(et_matrix_translateY.getText().toString());
		// 保存平移数据
		matrix.postTranslate(dx, dy);
		// 将matrix设置到imageView
		iv_matrix_icon.setImageMatrix(matrix);
	}

	public void clearMatrix(View view)
	{
		matrix.reset();
		// 将matrix设置到imageView
		iv_matrix_icon.setImageMatrix(matrix);
	}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:padding="10dp" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="50dip"
        android:layout_marginTop="10dip"
        android:orientation="horizontal" >

        <EditText
            android:id="@+id/et_matrix_scale"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1.0"
            android:hint="缩放比例"
            android:text="0.25" />

        <EditText
            android:id="@+id/et_matrix_rotate"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1.0"
            android:hint="旋转角度"
            android:onClick="rotateBitmap"
            android:text="30" />

        <EditText
            android:id="@+id/et_matrix_translateX"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1.0"
            android:hint="X偏移"
            android:text="10" />

        <EditText
            android:id="@+id/et_matrix_translateY"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1.0"
            android:hint="y偏移"
            android:text="10" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="50dip"
        android:layout_marginTop="10dip"
        android:orientation="horizontal" >

        <Button
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1.0"
            android:onClick="scaleBitmap"
            android:text="缩放" />

        <Button
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1.0"
            android:onClick="rotateBitmap"
            android:text="旋转" />

        <Button
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1.0"
            android:onClick="translateBitmap"
            android:text="移动" />

        <Button
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1.0"
            android:onClick="clearMatrix"
            android:text="还原" />
    </LinearLayout>

    <ImageView
        android:id="@+id/iv_matrix_icon"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scaleType="matrix"
        android:src="@drawable/ic_launcher" />

</LinearLayout>

Shape图形图片

在Android中, 可以通过<shap>来配置自定义图形
这个先在布局文件里面定义好相应的视图文件,
然后将它的背景设置成Shape图形图片就可以了
  <Button
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:background="@drawable/shape_test"
      android:text="使用Shape做的按钮" />
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >

    <!-- 圆角
    	android:radius指定的是半径
     -->
    <corners android:radius="8dp" >
    </corners>

    <!-- 描边(边框)
    	android:dashGap 一个虚线的长度
    	android:dashWidth 虚线之间的间距
    	android:width 边框的宽度
    	android:color 边框颜色
     -->
    <stroke
        android:dashGap="2dp"
        android:dashWidth="10dp"
        android:width="4dp"
        android:color="#00ff00" />

    <!-- 尺寸:就是这个视图对象的宽高 -->
    <size
        android:height="40dp"
        android:width="100dp" />

    <!-- 内部单色填充 -->
    <solid android:color="#ff0000" />

    <!-- 内部渐变色填充:
    	android:centerColor 中间颜色
    	android:endColor 结束颜色
    	android:startColor 开始颜色
    	android:angle 色变的方向
     -->
    <gradient
        android:centerColor="#ffffff"
        android:endColor="#ffff00"
        android:startColor="#0000ff" 
        android:angle="90">
    </gradient>

</shape>

Selector多状态图片

Selector+图片
selector多状态图形在可以在正常,按下,选中等状态下显示不同的图形, 在应用中十分常用
在使用时可以把它的xml文件看作一个图片
它可以与图片或<shap>一起使用
这个和上面也差不多,先在布局文件里面定义好相应的视图,
然后将它的背景设置成drawable文件就可以了
<ImageView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_gravity="center_horizontal"
      android:background="@drawable/select_drawble"
      android:onClick="clickIV" />
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- 这两个必须按照顺序来写,如果反过来
    	就不能生效了,比如没有按下去的时候选择正常的图片,
    	按下去后,因为正常的图片在前面,符合约束,所以也显示正常情况下的图片了
     -->
    <!-- 按下的图片 (必须写在前面) -->
    <item android:drawable="@drawable/main_index_search_pressed" android:state_pressed="true"></item>
    <!-- 正常情况下的图片 -->
    <item android:drawable="@drawable/main_index_search_normal"></item>

</selector>
Selector+shape
<Button
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/selector_shape"
            android:text="使用Selector+Shape做的按钮" />
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:state_pressed="true">
        <shape>
            <corners android:radius="5dp"/>
            <solid android:color="#ff0000"/>
            <padding android:top="5dp" android:bottom="5dp"/>
        </shape>
    </item>
     <item>
        <shape>
            <corners android:radius="10dp"/>
            <solid android:color="#00ff00"/>
            <padding android:top="5dp" android:bottom="5dp"/>
        </shape>
    </item>
</selector>

9patch图片(以.9.png结尾)

.9.png图片是一种特别的png图片, 它在放大显示时不会失真

.9.png图片可以分为三种类型区域
	正中间区域: 可向水平和垂直方向复制扩展
	中上, 中下, 中左与中右区域: 只能向一个方向扩展
	四个角区域: 大小不会变化
如何制作?
	准备一张png图片
	然后在sdk的tools里面启动draw9patch.bat程序
	然后用这个程序来打开png图片

在这里插入图片描述

然后将这张图片设置成背景就行了

绘制自定义图形

package com.jane.graphics;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.os.Bundle;
import android.view.View;

public class DrawTestActivity extends Activity
{

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(new MyView(this));
	}

	class MyView extends View
	{
		private ShapeDrawable shapeDrawable;
		private Paint paint;

		public MyView(Context context)
		{
			super(context);
			shapeDrawable = new ShapeDrawable(new OvalShape());
			shapeDrawable.getPaint().setColor(Color.RED);// 指定颜色
			shapeDrawable.setBounds(10, 10, 200, 100);// 指定位置

			paint = new Paint();
			paint.setColor(Color.BLUE); // 颜色
			paint.setTextSize(20);// 字体大小
			paint.setTypeface(Typeface.DEFAULT_BOLD);// 粗体字
			paint.setAntiAlias(true);// 消除锯齿
		}

		@Override
		protected void onDraw(Canvas canvas)
		{
			super.onDraw(canvas);
			// 画绿色背景
			canvas.drawColor(Color.GREEN);
			// 画椭圆
			shapeDrawable.draw(canvas);// 将自己画到画布上
			// 画文本,这里指定的坐标是左下角的坐标
			canvas.drawText("画文字", 10, 120, paint);
		}
	}
}

copyright@ 2020-2028  安卓源码空间网版权所有   

备案号:豫ICP备2023034476号-1号