Android两种不同的方法去实现图像的放大与缩小

其实不算两种不同的方法,只是一个方法用的是硬编码,而另一个用的是MVC设计模式,用的都是同一个类Matrix。

第一种:硬编码方式

MainActivity.java

Code:
  1. package com.android.yhb;  
  2.   
  3. import android.app.Activity;  
  4. import android.graphics.Bitmap;  
  5. import android.graphics.BitmapFactory;  
  6. import android.graphics.Matrix;  
  7. import android.os.Bundle;  
  8. import android.util.DisplayMetrics;  
  9. import android.util.Log;  
  10. import android.view.View;  
  11. import android.widget.AbsoluteLayout;  
  12. import android.widget.Button;  
  13. import android.widget.ImageView;  
  14.   
  15. @SuppressWarnings("deprecation")  
  16. public class MainActivity extends Activity {  
  17.     private ImageView mImageView;  
  18.     private Button mButton01;  
  19.     private Button mButton02;  
  20.     private AbsoluteLayout layout1;  
  21.     private Bitmap bmp;  
  22.     private int id = 0;  
  23.     private int displayWidth;  
  24.     private int displayHeight;  
  25.     private float scaleWidth = 1;  
  26.     private float scaleHeight = 1;  
  27.   
  28.     /** Called when the activity is first created. */  
  29.     @Override  
  30.     public void onCreate(Bundle savedInstanceState) {  
  31.         super.onCreate(savedInstanceState);  
  32.         setContentView(R.layout.main);  
  33.   
  34.         /* 取得屏幕分辨率的大小 */  
  35.         DisplayMetrics dm = new DisplayMetrics();  
  36.         getWindowManager().getDefaultDisplay().getMetrics(dm);  
  37.         displayWidth = dm.widthPixels;  
  38.         /* 加载资源 */  
  39.         bmp = BitmapFactory.decodeResource(getResources(), R.drawable.me);  
  40.         mImageView = (ImageView) findViewById(R.id.imageView);  
  41.         layout1 = (AbsoluteLayout) findViewById(R.id.layout);  
  42.         mButton01 = (Button) findViewById(R.id.button_small);  
  43.         mButton02 = (Button) findViewById(R.id.button_big);  
  44.   
  45.         /* 计算出来的高度要减去Button的高度 */  
  46.         displayHeight = dm.heightPixels-mButton01.getHeight();  
  47.         Log.e("Tag"" " + displayHeight);//这块通过Log输出发现并没有获得Button的高度,不知道怎么回事!  
  48.         /* 缩小监听 */  
  49.         mButton01.setOnClickListener(new Button.OnClickListener() {  
  50.             @Override  
  51.             public void onClick(View v) {  
  52.                 small();  
  53.             }  
  54.         });  
  55.   
  56.         /* 放大监听 */  
  57.         mButton02.setOnClickListener(new Button.OnClickListener() {  
  58.             @Override  
  59.             public void onClick(View v) {  
  60.                 big();  
  61.             }  
  62.         });  
  63.     }  
  64.   
  65.     /* small method */  
  66.     private void small() {  
  67.         int bmpWidth = bmp.getWidth();  
  68.         int bmpHeight = bmp.getHeight();  
  69.         /* 设置图片缩小比例 */  
  70.         double scale = 0.8;  
  71.         /* 计算出缩小后的长宽 */  
  72.         scaleWidth = (float) (scaleWidth * scale);  
  73.         scaleHeight = (float) (scaleHeight * scale);  
  74.   
  75.         /* 产生Resize后的Bitmap对象 */  
  76.         Matrix matrix = new Matrix();  
  77.         matrix.postScale(scaleWidth, scaleHeight);  
  78.         Bitmap resizeBmp = Bitmap.createBitmap(bmp, 00, bmpWidth, bmpHeight,  
  79.                 matrix, true);  
  80.   
  81.         if (id == 0) {  
  82.             /* 如果是第一次单击缩小按钮,就删除原来默认的ImageView */  
  83.             layout1.removeView(mImageView);  
  84.         } else {  
  85.             /* 不然就删除上次放大或缩小产生的ImageView */  
  86.             layout1.removeView((ImageView) findViewById(id));  
  87.         }  
  88.         /* 产生新的ImageView,放入Resize后的Bitmap对象,再放入Layout中 */  
  89.         id++;  
  90.         ImageView imageView = new ImageView(MainActivity.this);  
  91.         imageView.setId(id);  
  92.         imageView.setImageBitmap(resizeBmp);  
  93.         layout1.addView(imageView);  
  94.         setContentView(layout1);  
  95.   
  96.         /* 将mButton02设置成可点击的 */  
  97.         mButton02.setEnabled(true);  
  98.     }  
  99.   
  100.     /* big method */  
  101.     private void big() {  
  102.         int bmpWidth = bmp.getWidth();  
  103.         int bmpHeight = bmp.getHeight();  
  104.         /* 放大变量 */  
  105.         double scale = 1.1;  
  106.         /* 放大以后的宽高,一定要强制转换为float型的 */  
  107.         scaleWidth = (float) (scaleWidth * scale);  
  108.         scaleHeight = (float) (scaleHeight * scale);  
  109.   
  110.         /* 产生resize后的Bitmap对象 */  
  111.         Matrix matrix = new Matrix();  
  112.         matrix.postScale(scaleWidth, scaleHeight);  
  113.         Bitmap resizeBmp = Bitmap.createBitmap(bmp, 00, bmpWidth, bmpHeight,  
  114.                 matrix, true);  
  115.   
  116.         if (id == 0) {  
  117.             /* 如果是第一次按就删除原来设置的ImageView */  
  118.             layout1.removeView(mImageView);  
  119.         } else {  
  120.             /* 如果不是第一次按,就删除上次放大or缩小的ImageView */  
  121.             layout1.removeView((ImageView) findViewById(id));  
  122.         }  
  123.         /* 产生新的ImageView,放入Resize后的Bitmap对象,再放入Layout中 */  
  124.         id++;  
  125.         ImageView imageView = new ImageView(MainActivity.this);  
  126.         imageView.setId(id);  
  127.         imageView.setImageBitmap(resizeBmp);  
  128.         layout1.addView(imageView);  
  129.         setContentView(layout1);  
  130.   
  131.         /* 如果再放大会超过屏幕大小,就把Button disable */  
  132.         if (scaleWidth * scale * bmpWidth > displayWidth  
  133.                 || scaleHeight * scale * bmpHeight > displayHeight) {  
  134.             Log.e("Tag"" " + scaleHeight * scale * bmpHeight);  
  135.             mButton02.setEnabled(false);  
  136.         }  
  137.     }  
  138. }  

Main.xml

Code:
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <AbsoluteLayout  
  3.     android:id="@+id/layout"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent"  
  6.     xmlns:android="http://schemas.android.com/apk/res/android"  
  7.     >  
  8. <Button  
  9.     android:id="@+id/button_big"  
  10.     android:layout_width="wrap_content"  
  11.     android:layout_height="wrap_content"  
  12.     android:text="@string/big"  
  13.     android:layout_x="61px"  
  14.     android:layout_y="380px"  
  15.     >  
  16. </Button>  
  17. <Button  
  18.     android:id="@+id/button_small"  
  19.     android:layout_width="wrap_content"  
  20.     android:layout_height="wrap_content"  
  21.     android:text="@string/small"  
  22.     android:layout_x="175px"  
  23.     android:layout_y="380px"  
  24.     >  
  25. </Button>  
  26. <ImageView  
  27.     android:id="@+id/imageView"  
  28.     android:layout_width="wrap_content"  
  29.     android:layout_height="wrap_content"  
  30.     android:src="@drawable/me"  
  31.     android:layout_x="0px"  
  32.     android:layout_y="0px"  
  33.     >  
  34. </ImageView>  
  35. </AbsoluteLayout>  

关于布局这块,那么细致的去确定位置坐标,真是有点麻烦,我是用一款专门的设计软件去做的,这个软件就在我的下载里面,大家可以下载看看。

实现的效果如图1:

(图1)此图为放大到最大时的截图,放大按钮被置为disabled。

注意:由于在代码105-107行有强制类型转换,所以每次放大后的长宽高都有误差,所以不是每次放大都是精准的,同理,缩小也一样。

第二种在XML里设计(MVC)

自定义View.java

Code:
  1. package com.android.yhb;  
  2.   
  3. import android.content.Context;  
  4. import android.graphics.Bitmap;  
  5. import android.graphics.Canvas;  
  6. import android.graphics.Matrix;  
  7. import android.graphics.drawable.BitmapDrawable;  
  8. import android.view.View;  
  9.   
  10. public class GameView extends View implements Runnable {  
  11.     private int BitmapWidth = 0;  
  12.     private int BitmapHeight = 0;  
  13.   
  14.     Bitmap mBitmap = null;  
  15.   
  16.     float Scale = 1.0f;  
  17.     Matrix mMatrix = new Matrix();  
  18.   
  19.     public GameView(Context context) {  
  20.         super(context);  
  21.         // TODO Auto-generated constructor stub  
  22.         mBitmap = ((BitmapDrawable) getResources().getDrawable(  
  23.                 R.drawable.myicon)).getBitmap();  
  24.         BitmapWidth = mBitmap.getWidth();  
  25.         BitmapHeight = mBitmap.getHeight();  
  26.   
  27.         new Thread(this).start();  
  28.     }  
  29.   
  30.     public void run() {  
  31.         while (!Thread.currentThread().isInterrupted()) {  
  32.             try {  
  33.                 Thread.sleep(100);  
  34.             } catch (InterruptedException e) {  
  35.                 Thread.currentThread().interrupt();  
  36.             }  
  37.   
  38.             postInvalidate();  
  39.         }  
  40.     }  
  41.   
  42.     public void onDraw(Canvas canvas) {  
  43.         super.onDraw(canvas);  
  44.         mMatrix.reset();  
  45.         mMatrix.postScale(Scale, Scale);  
  46.         Bitmap mBitmap2 = Bitmap.createBitmap(mBitmap, 00, BitmapWidth,  
  47.                 BitmapHeight, mMatrix, true);  
  48.         GameView.drawImage(canvas, mBitmap2, (320 - BitmapWidth) / 210);  
  49.         mBitmap2 = null;  
  50.     }  
  51.   
  52.     public static void drawImage(Canvas canvas, Bitmap bitmap, int x, int y) {  
  53.         canvas.drawBitmap(bitmap, x, y, null);  
  54.     }  
  55.   
  56. }  

MainActivity.java

Code:
  1. package com.android.yhb;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.util.Log;  
  6. import android.view.KeyEvent;  
  7.   
  8. public class MainActivity extends Activity {  
  9.     GameView myGameView = null;  
  10.     /** Called when the activity is first created. */  
  11.     @Override  
  12.     public void onCreate(Bundle savedInstanceState) {  
  13.         super.onCreate(savedInstanceState);  
  14.         /*setContentView(R.layout.main);*/  
  15.         myGameView = new GameView(this);  
  16.         setContentView(myGameView);  
  17.     }  
  18.   
  19.     public boolean onKeyDown(int keycode, KeyEvent event) {  
  20.         if (keycode == KeyEvent.KEYCODE_DPAD_DOWN) {  
  21.             if (myGameView.Scale > 0.1) {  
  22.                 Log.e("Tag""=====>KEYCODE_DPAD_UP");  
  23.                 myGameView.Scale -= 0.1;  
  24.             }  
  25.         } else if (keycode == KeyEvent.KEYCODE_DPAD_UP) {  
  26.             if (myGameView.Scale < 2.5) {  
  27.                 myGameView.Scale += 0.1;  
  28.             }  
  29.         }  
  30.         return true;  
  31.     }  
  32. }

main.xml

Code:
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent"  
  6.     >  
  7. <!--<com.android.yhb.GameView  
  8.     android:layout_width="wrap_content"  
  9.     android:layout_height="wrap_content"  
  10.     />  
  11. --><!--不知怎么搞的,在这里不能设置Tag,所以注释了,在MainActivity.java里面实例化了一个-->
  12. <TextView    
  13.     android:layout_width="fill_parent"   
  14.     android:layout_height="wrap_content"   
  15.     android:text="@string/hello"  
  16.     />  
  17. </LinearLayout>  

 效果图

这里注意应该把按键监听语句放在MainActivity.java代码里面,不应该放在自定义View里面进行监听,这样会出错。

总结:

  1.  /* 加载资源 */  bmp = BitmapFactory.decodeResource(getResources(), R.drawable.me);  或mBitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.myicon)).getBitmap();
  2. 第二个通过键盘去放大缩小,我试着通过添加按钮区控制,但是总是出错。
  3. 通过对代码的比较,显然易见,MVC的代码更清楚,但是用硬编码有硬编码的好处,硬代码编程运行时可以加快调用速度,而MVC会增加内存。
  4. 在Android中不允许ImageView在产生后,动态修改其长度和宽度,所以为了实现图片放大缩小功能,使用的方式是当用户在单击放大或缩小的按钮时,除了将图片作放大或缩小的动作外,并将原来Layout中ImageView删除,重新产生一个新的ImageView,指定图片给它后,再放入Layout里,用户看来,就好像同一张图片再放大或缩小。即方法一的代码。
  5. 代码有很多不足,希望大家自己去修改,也希望高人能在此给予指点。

你可能感兴趣的:(android,mvc,layout,float,button,Matrix)