Android学习笔记_66_图片处理专题

  1、图片缩放:不解析整个图片信息。

public class DemoActivity extends Activity {

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        ImageView iv = (ImageView) this.findViewById(R.id.iv);

//        BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();

//        //按1/8的大小加载到内存 

//        bmpFactoryOptions.inSampleSize = 8;

//        Bitmap bm = BitmapFactory.decodeFile("/sdcard/img.jpg",bmpFactoryOptions);

//        iv.setImageBitmap(bm);

        

        // 

        //1. 首先得到屏幕的宽高

        Display currentDisplay = getWindowManager().getDefaultDisplay();

        int dw = currentDisplay.getWidth();

        int dh = currentDisplay.getHeight();

        // 2. 获取图片的宽度和高度 

        BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();

        // 设置inJustDecodeBounds = true ,只会解析文件头信息;

        bmpFactoryOptions.inJustDecodeBounds = true;

        // 不会真正的解析这个位图 

        Bitmap bmp = BitmapFactory.decodeFile("/sdcard/img.jpg", bmpFactoryOptions);

        //得到图片的宽度和高度 

        int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)dh);

        int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)dw);

        Log.v("HEIGHTRATIO",""+heightRatio);

        Log.v("WIDTHRATIO",""+widthRatio);



        //真正的解析位图 

        bmpFactoryOptions.inJustDecodeBounds = false;

   

        if(heightRatio>widthRatio){

            bmpFactoryOptions.inSampleSize = heightRatio;

        }else{

            bmpFactoryOptions.inSampleSize = widthRatio;

        }

        bmp = BitmapFactory.decodeFile("/sdcard/img.jpg", bmpFactoryOptions);

        

        iv.setImageBitmap(bmp);

    }

}

  2、ExifInterface获取或设置图片的exif信息:

public class DemoActivity extends Activity {

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        

        try {

            ExifInterface  exif = new ExifInterface("sdcard/img.jpg");

            System.out.println( exif.getAttribute(ExifInterface.TAG_DATETIME));

            System.out.println( exif.getAttribute(ExifInterface.TAG_IMAGE_LENGTH));

            System.out.println( exif.getAttribute(ExifInterface.TAG_IMAGE_WIDTH));    

            exif.setAttribute("camera", "柯达相机");    

            System.out.println( exif.getAttribute("camera"));

        } catch (Exception e) {

            e.printStackTrace();

        }



    }

}

      3、从图库里面选择一个图片,然后将它设置到ImageView。

public class DemoActivity extends Activity {

    ImageView iv;

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        iv = (ImageView) this.findViewById(R.id.iv);

    }

    

    public void click(View view){

        //选择图库意图,打开图库

        Intent intent = new Intent(Intent.ACTION_PICK);

        intent.setType("image/*");

        startActivityForResult(intent, 0);

    }



    @Override

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        if(data!=null){

            //图片的uri

            Uri uri = data.getData() ;

            iv.setImageURI(uri);

        }

        super.onActivityResult(requestCode, resultCode, data);

    }

}

  4、创建图片(bitmap)的拷贝:

public class DemoActivity extends Activity{

    ImageView iv1;

    ImageView iv2;

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        iv1= (ImageView) this.findViewById(R.id.iv1);

        iv2= (ImageView) this.findViewById(R.id.iv2);

    }

    

    public void click(View view){

        Intent intent = new Intent(Intent.ACTION_PICK);

        intent.setType("image/*");

        startActivityForResult(intent, 0);

    }

    @Override

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        if(data!=null){

            //图片的uri

            Uri uri = data.getData() ;

            iv1.setImageURI(uri);

            // 获取第一个图片 的拷贝 设置到iv2的控件里面 

            try {

                //通过uri获取一个流对象。getContentResolver().openInputStream(uri)

                Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));

                //图片缩放

                Matrix matrix = new Matrix();

//                matrix.setValues(new float[] {

//                    2, 0, 0,

//                    0, 1, 0,

//                    0, 0, 1

//                });//矩阵缩放

//                matrix.setScale(1.5f, 1.0f);//水平方向为1.5倍,垂直方向不做改变

//                matrix.postTranslate(bitmap.getWidth(), 1.0f);//与setScale可以实现图片翻转

//                matrix.setRotate(30);

                //画笔

                Paint paint = new Paint();

                paint.setAntiAlias(true);//消除锯齿

                matrix.setRotate(15);//图片旋转

                //得到一个大小 配置跟原图一样的空白的位图 

                //Bitmap  alterbitmap  = Bitmap.createBitmap(bitmap.getWidth()*2, bitmap.getHeight(), bitmap.getConfig());

                Bitmap    alteredBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(),

                        matrix, false);

                //画布对象

                Canvas canvas = new Canvas();

                //将图片流bitmap应用到画布上

                canvas.drawBitmap(bitmap, matrix, paint);    

                iv2.setImageBitmap(alteredBitmap);

            } catch (Exception e) {

                e.printStackTrace();

            }

        }

        super.onActivityResult(requestCode, resultCode, data);

    }

}

最后一个:filter解释
true if the source should be filtered. Only applies if the matrix contains more than just translation.
当进行的不只是平移变换时,filter参数为true可以进行滤波处理,有助于改善新图像质量;flase时,计算机不做过滤处理。

图片裁剪,可用这个方法:
Bitmap source:要从中截图的原始位图
int x: 起始x坐标
int y:起始y坐标
int width: 要截的图的宽度
int height:要截的图的高度

要想imageView.setImageMatrix()方法起作用,xml得配置android:scaleType="matrix"

matrix.setRotate和matrix.postRotate的区别:
post...:平移、旋转等效果可以叠加在一起;
set...:前一种效果会消失,只有后来的操作,即它会重置Matrix

 

 5、图片合成:

public class DemoActivity extends Activity {

   Bitmap basebitmap;

   Canvas canvas ;

   Paint paint;

   ImageView iv;

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        iv = (ImageView) this.findViewById(R.id.iv);

    }

    public void select1(View view){

        Intent intent = new Intent(Intent.ACTION_PICK);

        intent.setType("image/*");

        startActivityForResult(intent, 10);

        // 从图库里面获取第一个图片 

    }

    public void save(View view){

        File file = new File("/sdcard/1.jpg");

        FileOutputStream fos;

        try {

            fos = new FileOutputStream(file);

            basebitmap.compress(CompressFormat.JPEG, 100, fos);

            //显示的发送一条广播 

            //sd卡挂载的广播 

            Intent intent = new Intent(Intent.ACTION_MEDIA_MOUNTED,Uri.parse("file://"+Environment.getExternalStorageDirectory()));

            sendBroadcast(intent);

        } catch (FileNotFoundException e) {

            e.printStackTrace();

        }

    }

    

    public void select2(View view){

           Intent intent = new Intent(Intent.ACTION_PICK);

        intent.setType("image/*");

        startActivityForResult(intent, 20);

        // 从图库里面获取第一个图片 

    }

    @Override

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        if(requestCode==10){

            if(data!=null){

                Uri uri = data.getData();

                try {

                    Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));

                

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

                    canvas = new Canvas(basebitmap);

                    paint = new Paint();

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

                    

                } catch (Exception e) {

                    e.printStackTrace();

                }

            }

        }else if(requestCode==20){

            if(data!=null){

                Uri uri = data.getData();

                //把第二张位图的内容 画在 basebitmap上 

                try {

                    Bitmap bitmap = BitmapFactory.decodeStream(  getContentResolver().openInputStream(uri));

                    paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.MULTIPLY));

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

                    iv.setImageBitmap(basebitmap);

                } catch (Exception e) {

                    e.printStackTrace();

                }

                

            }

        }

        super.onActivityResult(requestCode, resultCode, data);

    }

}

  6、根据路径Path绘制文字:

public class DemoActivity extends Activity {

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(new MyView(this));

    }

    private class MyView extends View{

        public MyView(Context context) {

            super(context);

        }

        @Override

        protected void onDraw(Canvas canvas) {



            Paint paint = new Paint();

            paint.setColor(Color.GREEN);

            paint.setTextSize(20);

            paint.setTypeface(Typeface.DEFAULT);

            Path p = new Path();

            p.moveTo(20, 20);

            p.lineTo(100, 150);

            p.lineTo(200, 220);

            canvas.drawTextOnPath("Hello this is text on a path", p, 0, 0, paint);

            super.onDraw(canvas);

        }

    }

}

  7、绘图(根据手指移动创建图片并保存):

public class DemoActivity extends Activity {

    ImageView iv;

    Bitmap bitmap;

    Canvas canvas;

    Paint paint;

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        iv = (ImageView) this.findViewById(R.id.iv);

        Display diaplay = getWindow().getWindowManager().getDefaultDisplay();

        int height = diaplay.getHeight() - 40;

        int width = diaplay.getWidth();

        bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

        iv.setImageBitmap(bitmap);

        canvas = new Canvas(bitmap);

        paint= new Paint();

        paint.setColor(Color.GREEN);

        paint.setStrokeWidth(10);

        iv.setOnTouchListener(new OnTouchListener() {



            float startx = 0;

            float starty = 0;



            @Override

            public boolean onTouch(View v, MotionEvent event) {

                switch (event.getAction()) {

                case MotionEvent.ACTION_DOWN:

                    startx =  event.getX();

                    starty =  event.getY();

                    

                    break;

                case MotionEvent.ACTION_MOVE:

                    float x =  event.getX();

                    float y =  event.getY();

                    canvas.drawLine(startx, starty, x, y, paint);

                    startx =  event.getX();

                    starty =  event.getY();

                    

                    //通知imageview更新界面 

                    iv.invalidate();

                    break;

                case MotionEvent.ACTION_UP:

                    float endx =  event.getX();

                    float endy =  event.getY();

                    canvas.drawLine(startx, starty, endx, endy, paint);

                    //通知imageview更新界面 

                    iv.invalidate();

                    break;

                default:

                    break;

                }



                return true;

            }

        });



    }



    public void save(View view) {

        File file = new File("/sdcard/"+System.currentTimeMillis()+".jpg");

        FileOutputStream fos;

        try {

            fos = new FileOutputStream(file);

        

            bitmap.compress(CompressFormat.JPEG, 100, fos);

            //显示的发送一条广播 

            //sd卡挂载的广播 

            Intent intent = new Intent(Intent.ACTION_MEDIA_MOUNTED,Uri.parse("file://"+Environment.getExternalStorageDirectory()));

            sendBroadcast(intent);



            

        } catch (FileNotFoundException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

    }

}

 8、矩阵Matrix

   

Matrix的操作,总共分为translate(平移),rotate(旋转),scale(缩放)和skew(倾斜)四种,每一种变换在Android的API里都提供了set, post和pre三种操作方式,除了translate,其他三种操作都可以指定中心点。

set是直接设置Matrix的值,每次set一次,整个Matrix的数组都会变掉。

post是后乘,当前的矩阵乘以参数给出的矩阵。可以连续多次使用post,来完成所需的整个变换。

例如,要将一个图片旋转30度,然后平移到(100,100)的地方,那么可以这样做:

Matrix m =  new  Matrix();  

m.postRotate(30 );  

m.postTranslate(100 ,  100 ); 

  pre是前乘,参数给出的矩阵乘以当前的矩阵。所以操作是在当前矩阵的最前面发生的。例如上面的例子,如果用pre的话

Matrix m =  new  Matrix();  

m.setTranslate(100 ,  100 );  

m.preRotate(30 )

旋转、缩放和倾斜都可以围绕一个中心点来进行,如果不指定,默认情况下,是围绕(0,0)点来进行。

public   class  MyView  extends  View {  

      

    private  Bitmap mBitmap;  

    private  Matrix mMatrix =  new  Matrix();  

      

    public  MyView(Context context) {  

        super (context);  

        initialize();  

    }  

  

    private   void  initialize() {  

          

        Bitmap bmp = ((BitmapDrawable)getResources().getDrawable(R.drawable.show)).getBitmap();  

        mBitmap = bmp;  

        /*首先,将缩放为100*100。这里scale的参数是比例。有一点要注意,如果直接用100/  

bmp.getWidth()的话,会得到0,因为是整型相除,所以必须其中有一个是float型的,直接用100f就好。*/   

        mMatrix.setScale(100f/bmp.getWidth(), 100f/bmp.getHeight());  

                //平移到(100,100)处   

        mMatrix.postTranslate(100 ,  100 );  

                //倾斜x和y轴,以(100,100)为中心。   

        mMatrix.postSkew(0 .2f,  0 .2f,  100 ,  100 );  

    }  

      

    @Override   protected   void  onDraw(Canvas canvas) {  

//      super.onDraw(canvas);  //如果界面上还有其他元素需要绘制,只需要将这句话写上就行了。   

          

        canvas.drawBitmap(mBitmap, mMatrix, null );  

    }  

}  

 

 

pre方法表示矩阵前乘,例如:变换矩阵为A,原始矩阵为B,pre方法的含义即是A*B



post方法表示矩阵后乘,例如:变换矩阵为A,原始矩阵为B,post方法的含义即是B*A



matrix.preScale(0.5f, 1);   

matrix.preTranslate(10, 0);  

matrix.postScale(0.7f, 1);    

matrix.postTranslate(15, 0);  

等价于:



translate(10, 0) -> scale(0.5f, 1) -> scale(0.7f, 1) -> translate(15, 0)



注意:后调用的pre操作先执行,而后调用的post操作则后执行。



set方法一旦调用即会清空之前matrix中的所有变换,例如:



matrix.preScale(0.5f, 1);   

matrix.setScale(1, 0.6f);   

matrix.postScale(0.7f, 1);   

matrix.preTranslate(15, 0);  

等价于



translate(15, 0) -> scale(1, 0.6f) ->  scale(0.7f, 1)



matrix.preScale (0.5f, 1)将不起作用。

 

 

 

你可能感兴趣的:(Android学习)