1. 程式人生 > >計算機表示圖形的幾種方法。

計算機表示圖形的幾種方法。

在這裡插入圖片描述
案例載入一張大圖
在android中當載入的圖片過大(解析度高)時導致圖片無法正常檢視甚至會報oom異常,所以當載入一張大圖時需要設定其縮放的比例係數

package com.example.loadBigImage;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Point;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;

public class MainActivity extends Activity {

	private ImageView iv;
	private int height;
	private int width;

	@SuppressWarnings("deprecation")
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		//用來顯示小狗的照片
		iv = (ImageView) findViewById(R.id.iv);
		
		//【1】獲取手機的解析度  windowmanager  smsManager telephoneManager
		WindowManager wm= (WindowManager) getSystemService(WINDOW_SERVICE);
		height = wm.getDefaultDisplay().getHeight();
		width = wm.getDefaultDisplay().getWidth();
		System.out.println("width:"+width+"-----height:"+height);
		
	//	Point point=new Point();
	//	wm.getDefaultDisplay().getSize(point);
	//	int width=point.x;
	//	int height=point.y;
	//	System.out.println("width:"+width+"-----height:"+height);
	}

	//載入一張大圖片
	public void click(View v){
		//建立一個位圖工廠的配置引數
		BitmapFactory.Options options=new Options();
		//解碼器不去真正地解析點陣圖  只獲取圖片的寬和高資訊
		options.inJustDecodeBounds=true;
		//載入圖片內容   申請記憶體超過16M(取決於裝置dvm分配的記憶體大小,無法改變)會報記憶體溢位錯誤  oom  out of memory 
		BitmapFactory.decodeFile("/mnt/sdcard/dog.jpg",options);
		//【2】獲取圖片的寬和高資訊
		int imgwidth=options.outWidth;
		int imgheight=options.outHeight;
	
		//【3】計算縮放比
		int scale=1;
		int scaleX=imgwidth/width;
		int scaleY=imgheight/height;
		if(scaleX>=scaleY&&scaleX>scale){
			scale=scaleX;
		}else if(scaleY>=scaleX&&scaleY>scale){
			scale=scaleY;
		}
		System.out.println("縮放比:"+scale);
		//[4]按照縮放比進行顯示   設定縮放參數
		options.inSampleSize=scale;//理解為原圖的取樣比,按照這個標準對原圖取樣將減少記憶體使用。
		//[5]按照縮放比 進行解析點陣圖
        options.inJustDecodeBounds=false;
		Bitmap bitmap=BitmapFactory.decodeFile("/mnt/sdcard/dog.jpg",options);
		//[6]把bitmap顯示到iv上
		iv.setImageBitmap(bitmap);
	}
}

1掌握WindowManager的使用
2瞭解BitmapFactory的使用
3理解縮放比例係數

建立一個原圖的副本
比如我們在美圖秀秀中對一張圖片進行操作後,儲存時提醒你儲存為副本或是覆蓋原圖,此時就應用到了建立原圖副本進行操作的邏輯。

package com.example.copybitmap;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		//顯示原圖
		ImageView iv_src=(ImageView) findViewById(R.id.iv_src);
		//顯示副本
		ImageView iv_copy=(ImageView) findViewById(R.id.iv_copy);
		
		//[1]先把dog.png圖片轉換成bitmap 顯示到iv_src上    getResource()  獲取當前工程中的資源
		Bitmap srcBitmap=BitmapFactory.decodeResource(getResources(), R.drawable.dog);
		//[1.1]操作圖片
	    //srcBitmap.setPixel(50, 50, Color.RED);//修改哪一點座標的顏色
		
		//TODO	iv_src.setImageBitmap(srcBitmap);
		//[2]建立原圖的副本
		//[2.1]建立一個模板  相當於建立了一個和原圖一樣的空白的白紙
		Bitmap copybitmap=Bitmap.createBitmap(srcBitmap.getWidth(),srcBitmap.getHeight(),srcBitmap.getConfig());
		//[2.2]想作畫需要一個畫筆
		Paint paint=new Paint();
		//[2.3]建立一個畫布  把白紙鋪到畫布上
		Canvas canvas=new Canvas(copybitmap);
		//[2.4]開始作畫
		canvas.drawBitmap(srcBitmap, new Matrix(), paint);
		//[2.5]操作畫出來的小狗照片
		for (int i = 0; i < 20; i++) {
			copybitmap.setPixel(100+i, 50, Color.RED);
		}
		//[3]把copybitmap顯示到iv_copy上
		iv_copy.setImageBitmap(copybitmap);
	}
}

在這裡插入圖片描述
圖片處理常用api
旋轉,縮放,平移,鏡面,倒影等。
在這裡插入圖片描述
在這裡插入圖片描述

//[2]建立原圖的副本
		//[2.1]建立一個模板  相當於建立了一個和原圖一樣的空白的白紙
		Bitmap copybitmap=Bitmap.createBitmap(srcBitmap.getWidth(),srcBitmap.getHeight(),srcBitmap.getConfig());
		//[2.2]想作畫需要一個畫筆
		Paint paint=new Paint();
		//[2.3]建立一個畫布  把白紙鋪到畫布上    
		Canvas canvas=new Canvas(copybitmap);
		//[2.4]開始作畫
		Matrix matrix=new Matrix();
		//[2.5]對圖片進行旋轉   設定旋轉角度  以及旋轉中心
	    //matrix.setRotate(20, srcBitmap.getWidth()/2, srcBitmap.getHeight()/2);
		//[2.6]對圖片進行縮放
		// matrix.setScale(0.5f, 0.5f);
		//[2.7]對圖片進行平移
		//matrix.setTranslate(30f, 0);
		//[2.8]鏡面效果   兩個方法一起用
		//matrix.setScale(-1.0f, 1);
		//post是在上一次修改基礎上再次進行修改       set每次操作都是最新的   會覆蓋上次的操作
		//matrix.postTranslate(srcBitmap.getWidth(), 0);//翻轉後再移動回原位置
		//[2.9]倒影效果
		  matrix.setScale(1, -1);
	    //post是在上一次修改基礎上再次進行修改       set每次操作都是最新的   會覆蓋上次的操作
		  matrix.postTranslate(0, srcBitmap.getHeight());
	
		canvas.drawBitmap(srcBitmap,matrix, paint);
	    
		//[3]把copybitmap顯示到iv_copy上
		iv_copy.setImageBitmap(copybitmap);

鏡面效果示意圖
在這裡插入圖片描述
畫畫板小應用(畫圖並將圖片儲存到sd卡)

public class MainActivity extends Activity {

	private Canvas canvas;
	private ImageView iv;
	private Bitmap srcBitmap;
	private Paint paint;
	private Bitmap copyBitmap;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		//用來顯示我們畫的內容
		
		iv = (ImageView) findViewById(R.id.iv);
		srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bg);
		//[2]獲取原圖的副本  相當於是一張空白的白紙
		
		copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
		//建立一個畫筆
		paint = new Paint();
		
		canvas = new Canvas(copyBitmap);
		//開始作畫
		canvas.drawBitmap(srcBitmap, new Matrix(), paint);
	//	canvas.drawLine(20, 30, 100, 100, paint);
		iv.setImageBitmap(copyBitmap);
		
		//[3]給iv設定一個觸控事件
		iv.setOnTouchListener(new OnTouchListener() {
			
			private int startX;
			private int startY;

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				int action=event.getAction();
				switch (action) {
				case MotionEvent.ACTION_DOWN://按下
					//獲取開始劃線的位置
					System.out.println("觸控view");
					startX = (int) event.getX();
					startY = (int) event.getY();
					break;
				case MotionEvent.ACTION_MOVE://移動
					//獲取結束位置
					int stopX=(int) event.getX();
					int stopY=(int) event.getY();
					//不停地劃線
					canvas.drawLine(startX, startY, stopX, stopY, paint);
					//再次顯示在iv上
					iv.setImageBitmap(copyBitmap);
					//更新一下開始座標和結束座標
					startX=stopX;
					startY=stopY;
							
					break;
				case MotionEvent.ACTION_UP://擡起
					break;
				}
				
				//True if the listener has consumed the event, false otherwise.
				return true;//true 監聽器處理完當前事件了  可以進行之後的監聽
			}
		});
		
	}
		//點選按鈕改變畫筆的顏色
		public void click1(View v){
			paint.setColor(Color.RED);
		}
	    //加粗
		public void click2(View v){
			paint.setStrokeWidth(5);
		}
		//儲存
		
		public void click3(View v){
			/**
			 * format 儲存圖片的格式
			 * quality 質量
			 * SystemClock.uptimeMillis()   當前手機的開機時間
			 */
			try {
				//儲存到sdcard  需要開啟sdcard許可權
				File file=new File(Environment.getExternalStorageDirectory().getPath(),SystemClock.uptimeMillis()+".png");
				FileOutputStream fos=new FileOutputStream(file);
				copyBitmap.compress(CompressFormat.PNG, 100, fos);
			
                //傳送一條廣播   欺騙系統圖庫的應用
				Intent intent=new Intent();
				//設定action
				intent.setAction(Intent.ACTION_MEDIA_MOUNTED);
				intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory()));
				//傳送一條廣播
				sendBroadcast(intent);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
}

在這裡插入圖片描述
在這裡插入圖片描述
撕衣服小案例
原理:兩張圖片疊放再一起,觸控上面那張穿衣服圖片的地方變透明,下方沒穿衣服的圖片就顯示出來。

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		//用來顯示操作後的圖片
		final ImageView iv=(ImageView) findViewById(R.id.iv);
		//[1]獲取要操作的圖片  原圖  穿衣服的
		Bitmap srcBitmap=BitmapFactory.decodeResource(getResources(), R.drawable.m2);
		//[2]建立一個副本   相當於一個和原圖大小一樣的白紙
		final Bitmap alterBitmap=Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
		//建立畫筆
		Paint paint=new Paint();
		//建立畫筆  對alterBitmap進行作畫操作     把白紙鋪到畫布上
		Canvas canvas=new Canvas(alterBitmap);
	    //開始作畫   按照srcBitmap作為模板作畫
		canvas.drawBitmap(srcBitmap, new Matrix(), paint);
		iv.setImageBitmap(alterBitmap);
		
		//[3]給iv設定一個觸控事件
		iv.setOnTouchListener(new OnTouchListener() {
			
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				//具體判斷一下觸控事件
				switch(event.getAction()){
				case MotionEvent.ACTION_MOVE:  //移動事件
					for (int i = -5; i <5; i++) {//移動一次,通過迴圈往外擴五個畫素,依次使其變透明。
						for (int j =-5; j < 5; j++) {
							if(Math.sqrt(i*i+j*j)<5){//撕一個圓
								//所到之處變透明
								try {
									alterBitmap.setPixel((int)event.getX()+i,(int)event.getY()+j, Color.TRANSPARENT);
								} catch (Exception e) {
								}
							}
						}
						
					}
				    //更新一下iv
				    iv.setImageBitmap(alterBitmap);
				    break;
				}
				return true;
			}
		});
	}
}

在這裡插入圖片描述