zoukankan      html  css  js  c++  java
  • 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)将不起作用。
  • 相关阅读:
    ios swift 支持cocoaPods
    iOS 国际化
    ios storyboard全解析 (二)
    ios storyboard全解析 (一)
    UML类图的几个关系自我总结,(入门级)
    crypt 病毒
    js思维导向图
    关于索引的使用
    SQL Server 索引结构及其使用
    关于js数组的那些事
  • 原文地址:https://www.cnblogs.com/lbangel/p/3612588.html
Copyright © 2011-2022 走看看