首页 > 代码库 > Camera图片特效处理综述(Bitmap的Pixels处理、Canvas/paint的drawBitmap处理、旋转图片、裁截图片、播放幻灯片浏览图片<线程固定时间显示一张>)

Camera图片特效处理综述(Bitmap的Pixels处理、Canvas/paint的drawBitmap处理、旋转图片、裁截图片、播放幻灯片浏览图片<线程固定时间显示一张>)

一种是直接对Bitmap的像素进行操作,如:叠加、边框、怀旧、(高斯)模糊、锐化(拉普拉斯变换)。

Bitmap.getPixels(srcPixels, 0, width, 0, 0, width, height);

  newR = (int) (pixR * alpha + layR * (1 - alpha));
    newR = Math.min(255, Math.max(0, newR));
    。。。
    srcPixels[pos] = Color.argb(newA, newR, newG, newB);

Bitmap.setPixels(srcPixels, 0, width, 0, 0, width, height);

 

 

另一种是使用画布Canvas自带的函数进行处理,如:圆角、倒影、色相、饱和度、亮度、涂鸦:

Canvas canvas = new Canvas();//创建 空白画布,或new Canvas(bitmap)创建有背景画布,根据情况选择

    Paint paint = new Paint();

    。。。

canvas.drawBitmap(bitmap, null, rect, paint);

 

 


使用画布Canvas自带的函数进行处理的代码,以圆角特效为例:

        //圆角特效        public static Bitmap getRoundCornerImage(Bitmap bitmap, int roundPixels, int width, int height )        {                          //创建一个和原始图片一样大小位图                Bitmap roundConcerImage = Bitmap.createBitmap(width, height, Config.ARGB_8888);                //创建带有位图roundConcerImage的画布                Canvas canvas = new Canvas(roundConcerImage);                //创建画笔                Paint paint = new Paint();                            //创建一个和原始图片一样大小的矩形                Rect rect = new Rect(0, 0, width, height);                                RectF rectF = new RectF(rect);                // 去锯齿                 paint.setAntiAlias(true);                //画一个和原始图片一样大小的圆角矩形                canvas.drawRoundRect(rectF, roundPixels, roundPixels, paint);                //设置相交模式                paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));                //把图片画到矩形去                canvas.drawBitmap(bitmap, null, rect, paint);                return roundConcerImage;        }
View Code

 

直接对Bitmap的像素进行处理的代码,以怀旧特效为例:

Handler handler = new Handler(){     @Override     public void handleMessage(Message msg) {                                   Drawable targetBitmapDrawable = new BitmapDrawable((Bitmap) msg.obj);// 将Bitmap转换为Drawable                  is.setImageDrawable(targetBitmapDrawable);     }   };    /**     * 怀旧效果     * @param bmp     * @return     */   private void oldRemeber(final Bitmap bmp)    {    Thread thread = new Thread() {    @Override    public void run() {        int width = bmp.getWidth();        int height = bmp.getHeight();        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);        int pixColor = 0;        int pixR = 0;        int pixG = 0;        int pixB = 0;        int newR = 0;        int newG = 0;        int newB = 0;        int[] pixels = new int[width * height];        bmp.getPixels(pixels, 0, width, 0, 0, width, height);        for (int i = 0; i < height; i++)        {            for (int k = 0; k < width; k++)            {                pixColor = pixels[width * i + k];                pixR = Color.red(pixColor);                pixG = Color.green(pixColor);                pixB = Color.blue(pixColor);                newR = (int) (0.393 * pixR + 0.769 * pixG + 0.189 * pixB);                newG = (int) (0.349 * pixR + 0.686 * pixG + 0.168 * pixB);                newB = (int) (0.272 * pixR + 0.534 * pixG + 0.131 * pixB);                int newColor = Color.argb(255, newR > 255 ? 255 : newR, newG > 255 ? 255 : newG, newB > 255 ? 255 : newB);                pixels[width * i + k] = newColor;            }        }                bitmap.setPixels(pixels, 0, width, 0, 0, width, height);             Message message = handler.obtainMessage();     message.obj = bitmap;     handler.sendMessage(message);    }    };    thread.start();    thread = null;    }    
View Code

 

 

涂鸦特效再说明:

canvas = new Canvas(originalBitmap);//以原图片为背景创建画布

canvas.drawLine(startX, startY, clickX, clickY, paint);//根据手指移动画线条

canvas.drawBitmap(finalBitmap, 0, 0,null);//

 

 

左右旋转图片再说明:

File MatrixLeftFile=new File(currentImagePath);            try {                  BitmapOrgLeft = BitmapFactory.decodeStream(new FileInputStream(MatrixLeftFile), null, RotateOptions);            }catch (FileNotFoundException e2) {  // TODO 自动生成的 catch 块  e2.printStackTrace();            }BitmapOrgLeft = Bitmap.createBitmap(BitmapOrgLeft, 0, 0, BitmapOrgLeft.getWidth(), BitmapOrgLeft.getHeight(), matrixleft, true);try {                                      bos = new BufferedOutputStream(new FileOutputStream(MatrixLeftFile));                                } catch (FileNotFoundException e1) {                                 // TODO 自动生成的 catch 块                                  e1.printStackTrace();                                }                                            /* 采用压缩转档方法 */                                           BitmapOrgLeft.compress(Bitmap.CompressFormat.JPEG, 100, bos);                                           /* 调用flush()方法,更新BufferStream */                                            try {                                                bos.flush();                                            } catch (IOException e) {                                                // TODO 自动生成的 catch 块                                               e.printStackTrace();                                            }                                                                  /* 结束OutputStream */                                             try {                                                bos.close();                                            } catch (IOException e) {                                                    // TODO 自动生成的 catch 块                                               e.printStackTrace();                                            }               imageAdapter.notifyDataSetChanged();                            //调用函数刷新图片                        Refresh_Rotating_Pictures();                                                 Toast.makeText(getBaseContext(),  "保存成功!", Toast.LENGTH_LONG).show();                             //及时的释放 Bitmap 对象                                            if(BitmapOrgLeft != null && !BitmapOrgLeft.isRecycled())                                           {                                                                         BitmapOrgLeft.recycle();                                                     BitmapOrgLeft = null;                                       } 
View Code

 

 

裁截图片再说明:

主要是两个函数和画布canvas的使用:

public void moveChooseArea(int move_x,int move_y){}:整体调整矩形的四条边,有最大最小限制。

private void pressLB(int x,int y)、 pressLT、 pressRB、 pressRT:调整相邻的某(左、上)两条边,有最大最小限制。

       canvas.drawRect(ChooseArea, mPaint); 
        mPaint.setColor(Color.BLUE); 
        canvas.drawRect(recLT, mPaint); 
        canvas.drawRect(recLB, mPaint); 
        canvas.drawRect(recRT, mPaint);    
        canvas.drawRect(recRB, mPaint); 
         
        canvas.drawRect(leftRectL, leftAreaPaint); 
        canvas.drawRect(leftRectR, leftAreaPaint); 
        canvas.drawRect(leftRectT, leftAreaPaint); 
        canvas.drawRect(leftRectB, leftAreaPaint);

package com.cutPicture;import android.content.Context;  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.graphics.RectF;  import android.graphics.Bitmap.Config;  import android.graphics.drawable.BitmapDrawable;  import android.util.AttributeSet;  import android.view.MotionEvent;  import android.widget.ImageView;  //http://www.cdtarena.com/gpx/201305/8653.html  public class MyCutView extends ImageView {        private final static int PRESS_LB = 0;//表示左下角矩形框       private final static int PRESS_LT = 1;//表示左上角矩形框       private final static int PRESS_RB = 2;//表示右下角矩形框       private final static int PRESS_RT = 3;//表示右上角矩形框         private Bitmap bitMap = null;               //原始图片       private RectF src = http://www.mamicode.com/null;                   //经过比例转换后的裁剪区域       private RectF dst = null;                   //图片显示区域,也就是drawBitmap函数中的目标dst       private RectF ChooseArea = null;            //选择区域                     private Paint mPaint = null;                //画笔       private Matrix matrix = null;               //矩阵             private int mx = 0;                         //存储触笔移动时,之前**的触笔的x坐标       private int my = 0;                         //存储触笔移动时,之前**的触笔的y坐标       private boolean touchFlag = false;          //触笔是否在屏幕之*?       private boolean cutFlag = false;            //是否点击了menu上的裁剪按钮       private int recFlag = -1;                   //用来存储触笔点击了哪个小矩形框(改变选择区域大小的小矩形框)       private boolean firstFlag = false;            private RectF recLT = null;                 //左上角的小矩形框       private RectF recRT = null;                 //右上角的小矩形框       private RectF recLB = null;                 //左下角的小矩形框       private RectF recRB = null;                 //右下角的小矩形框       private static final int LEFT_AREA_ALPHA = 50 * 255 / 100;      private RectF leftRectL = null;      private RectF leftRectR = null;      private RectF leftRectT = null;      private RectF leftRectB = null;      private Paint leftAreaPaint = null;            int padding=0;        public String editImagePath=null;    public MyCutView(Context context, AttributeSet attrs) {          super(context, attrs);          this.init();      }            public MyCutView(Context context) {          super(context);          this.init();      }             public void init(){          cutFlag = true;          recLT = new RectF();          recLB = new RectF();          recRT = new RectF();          recRB = new RectF();          dst = new RectF();          mPaint = new Paint();          mPaint.setColor(Color.RED);          mPaint.setStyle(Paint.Style.STROKE);      //将画笔的风格改为空心           ChooseArea = new RectF();          this.setPressRecLoc();          src = null;          firstFlag = true;                    //选择框之外的灰色区域,分成四个矩形框                     leftAreaPaint = new Paint();          leftAreaPaint.setStyle(Paint.Style.FILL);          leftAreaPaint.setAlpha(MyCutView.LEFT_AREA_ALPHA);      }            public void setBitmap(Bitmap bitmap){          BitmapDrawable bd = new BitmapDrawable(bitmap);          src = new RectF(0,0,bd.getIntrinsicWidth(),bd.getIntrinsicHeight());          this.bitMap = bitmap.copy(Config.ARGB_8888, true);                    this.setImageBitmap(bitMap);          leftRectB = new RectF();          leftRectL = new RectF();          leftRectR = new RectF();          leftRectT = new RectF();      }            public void imageScale(){          matrix = this.getImageMatrix();          matrix.mapRect(dst, src);          padding = this.getPaddingBottom();          /*        int width = bitMap.getWidth();          int height = bitMap.getHeight();          //dst.set(dst.left+padding,dst.top+padding,dst.right+padding,dst.bottom+padding);        if(height>width)        {            dst.set(dst.left,dst.top,width-7,height+100); 适用于android:layout_width="wrap_content"是FillParent并且没有android:layout_centerInParent="true"属性        }        else        {            dst.set(dst.left,dst.top,width-170,height+120);         }        */        int w=this.getWidth();        int h=this.getHeight();        //if(h>w)        {            dst.set(dst.left+2,dst.top+2,w-4,h-6);        }        //else        if(editImagePath!=null)        {            BitmapFactory.Options options = new BitmapFactory.Options();            options.inJustDecodeBounds = true;            BitmapFactory.decodeFile(editImagePath, options);            int tempH = options.outHeight;            if(tempH==1944)            {                dst.set(dst.left+2,dst.top+2,w-4,h-67);            }        }        ChooseArea = new RectF(dst);          this.setPressRecLoc();      }            public Bitmap getSubsetBitmap(){          float ratioWidth = bitMap.getWidth()/(float)(dst.right-dst.left);          float ratioHeight = bitMap.getHeight()/(float)(dst.bottom - dst.top);          int left = (int)((ChooseArea.left - dst.left) * ratioWidth);          int right = (int)(left + (ChooseArea.right - ChooseArea.left) * ratioWidth);          int top = (int)((ChooseArea.top - dst.top) * ratioHeight);          int bottom = (int)(top + (ChooseArea.bottom - ChooseArea.top) * ratioHeight);          src = new RectF(left,top,right,bottom);          firstFlag = true;          set_LeftArea_Alpha();          return Bitmap.createBitmap(bitMap, left, top, right-left, bottom-top);      }            //获得ChooseArea对象       public RectF getChooseArea(){          return ChooseArea;      }            public void moveChooseArea(int move_x,int move_y){          if(ChooseArea.left + move_x >= dst.left && ChooseArea.right + move_x <= dst.right          && ChooseArea.top + move_y >= dst.top && ChooseArea.bottom + move_y <= dst.bottom){              ChooseArea.set(ChooseArea.left + move_x,ChooseArea.top+move_y                      ,ChooseArea.right + move_x,ChooseArea.bottom+move_y);          }else{              if(ChooseArea.left + move_x < dst.left){                  ChooseArea.set(dst.left,ChooseArea.top                          ,ChooseArea.right+dst.left-ChooseArea.left,ChooseArea.bottom);              }              if(ChooseArea.right + move_x > dst.right){                  ChooseArea.set(ChooseArea.left+dst.right-ChooseArea.right,ChooseArea.top                          ,dst.right,ChooseArea.bottom);              }                            if(ChooseArea.top + move_y < dst.top){                  ChooseArea.set(ChooseArea.left,dst.top                          ,ChooseArea.right,ChooseArea.bottom+dst.top-ChooseArea.top);              }                            if(ChooseArea.bottom + move_y > dst.bottom){                  ChooseArea.set(ChooseArea.left,ChooseArea.top+dst.bottom-ChooseArea.bottom                          ,ChooseArea.right,dst.bottom);              }          }          this.setPressRecLoc();          mPaint.setColor(Color.GREEN);          this.invalidate();      }            public boolean onTouchEvent(MotionEvent event){          mPaint.setColor(Color.RED);                              if(event.getAction() == MotionEvent.ACTION_DOWN && cutFlag){              //System.out.println(event.getX() + "," + event.getY());                             mx = (int)event.getX();              my = (int)event.getY();              if(this.judgeLocation(mx,my)){                  touchFlag = true;                  mPaint.setColor(Color.GREEN);                  this.invalidate();                  return true;              }else{                                if(this.findPresseddst((int)event.getX(), (int)event.getY())){                      touchFlag = true;                      mPaint.setColor(Color.RED);                      return true;                  }              }          }                    if(event.getAction() == MotionEvent.ACTION_MOVE && touchFlag){              //判断是否点击了哪个个小矩形框               if(this.isOutOfArea((int)event.getX(), (int)event.getY())){                  return true;              }                            //www.cdtarena.com如果选择区域大小跟图像大小一样时,就不能移动               if(ChooseArea.left == dst.left && ChooseArea.top == dst.top &&                 ChooseArea.right == dst.right && ChooseArea.bottom == dst.bottom){              }else{                  this.moveChooseArea((int)event.getX() - mx, (int)event.getY() - my);                  mx = (int)event.getX();                  my = (int)event.getY();              }          }                              if(event.getAction() == MotionEvent.ACTION_UP){              recFlag = -1;              this.invalidate();              touchFlag = false;          }                    return super.onTouchEvent(event);      }                              private boolean isOutOfArea(int x,int y){          switch(recFlag){          case MyCutView.PRESS_LB:              this.pressLB(x - mx, y - my);              break;          case MyCutView.PRESS_LT:              this.pressLT(x - mx, y - my);              break;          case MyCutView.PRESS_RB:              this.pressRB(x - mx, y - my);              break;          case MyCutView.PRESS_RT:              this.pressRT(x - mx, y - my);              break;          default:return false;          }          mx = x;          my = y;          this.invalidate();          return true;      }            public boolean findPresseddst(int x,int y){          boolean returnFlag = false;          if(this.isInRect(x, y, recLB)){              recFlag = MyCutView.PRESS_LB;              returnFlag = true;          }else if(this.isInRect(x, y, recLT)){              recFlag = MyCutView.PRESS_LT;              returnFlag = true;          }else if(this.isInRect(x, y, recRB)){              recFlag = MyCutView.PRESS_RB;              returnFlag = true;          }else if(this.isInRect(x, y, recRT)){              recFlag = MyCutView.PRESS_RT;              returnFlag = true;          }                    return returnFlag;      }            public boolean isInRect(int x,int y,RectF rect){          if(x >= rect.left -20 && x <= rect.right + 20 && y > rect.top - 20 && y < rect.bottom + 20){              return true;          }          return false;      }            private void pressLB(int x,int y){          float left = ChooseArea.left + x;          float right = ChooseArea.right;          float top = ChooseArea.top;          float bottom = ChooseArea.bottom + y;          if(left <= right - 30 && left >= dst.left && bottom <= dst.bottom && bottom >= top + 30){                  ChooseArea.set(left,top,right,bottom);          }else{              if(left + x < dst.left){                  left = dst.left;              }                            if(bottom + y > dst.bottom){                  bottom = dst.bottom;              }                            if(ChooseArea.left + x > ChooseArea.right - 30){                  left = ChooseArea.right - 30;              }                            if(ChooseArea.bottom + y < ChooseArea.top + 30){                  bottom = ChooseArea.top + 30;              }              ChooseArea.set(left,top,right,bottom);          }          this.setPressRecLoc();      }                  private void pressLT(int x,int y){          float left = ChooseArea.left + x;          float right = ChooseArea.right;          float top = ChooseArea.top + y;          float bottom = ChooseArea.bottom;          if(left <= right - 30 && left >= dst.left && top <= bottom - 30 && top >= dst.top){              ChooseArea.set(left,top,right,bottom);          }else{              if(left < dst.left){                  left = dst.left;              }                            if(top < dst.top){                  top = dst.top;              }                            if(left > right - 30){                  left = right - 30;              }                            if(top > bottom - 30){                  top = bottom - 30;              }              ChooseArea.set(left,top,right,bottom);          }          this.setPressRecLoc();      }                  private void pressRT(int x,int y){          float left = ChooseArea.left;          float right = ChooseArea.right + x;          float top = ChooseArea.top + y;          float bottom = ChooseArea.bottom;                    if(right <= dst.right && right >= left + 30 && top <= bottom - 30 && top >= dst.top){              ChooseArea.set(left,top,right,bottom);          }else{              if(right > dst.right){                  right = dst.right;              }                            if(top < dst.top){                  top = dst.top;              }                            if(right < left + 30){                  right = left + 30;              }                            if(top > bottom - 30){                  top = bottom - 30;              }              ChooseArea.set(left,top,right,bottom);          }          this.setPressRecLoc();      }                  private void pressRB(int x,int y){          float left = ChooseArea.left;          float right = ChooseArea.right + x;          float top = ChooseArea.top;          float bottom = ChooseArea.bottom + y;                    if(right<= dst.right && right >= left + 30 && bottom <= dst.bottom && bottom >= top + 30){              ChooseArea.set(left,top,right,bottom);          }else{              if(right > dst.right){                  right = dst.right;              }                            if(bottom > dst.bottom){                  bottom = dst.bottom;              }                            if(right < left + 30){                  right = left + 30;              }                            if(bottom < top + 30){                  bottom = top + 30;              }              ChooseArea.set(left,top,right,bottom);          }          this.setPressRecLoc();      }            //每次改变选择区域矩形的大小或者移动,各角落上的小矩形也要改变它的Location       private void setPressRecLoc(){          recLT.set(ChooseArea.left-5,ChooseArea.top-5 , ChooseArea.left+5, ChooseArea.top+5);          recLB.set(ChooseArea.left-5,ChooseArea.bottom-5 , ChooseArea.left+5, ChooseArea.bottom+5);          recRT.set(ChooseArea.right-5,ChooseArea.top-5 , ChooseArea.right+5, ChooseArea.top+5);          recRB.set(ChooseArea.right-5,ChooseArea.bottom-5 , ChooseArea.right+5, ChooseArea.bottom+5);      }              public boolean judgeLocation(float x,float y){          float start_x = this.getChooseArea().left;          float start_y = this.getChooseArea().top;          float last_x = this.getChooseArea().right;          float last_y = this.getChooseArea().bottom;          //System.out.println("chubi:" + x + "," + y);           //System.out.println(start_y + "," + last_y);           if(x > start_x+10 && x < last_x-10 && y > start_y+10 && y < last_y-10){              return true;          }          return false;      }            public void onDraw(Canvas canvas){          super.onDraw(canvas);          if(firstFlag){              this.imageScale();              firstFlag = false;              mPaint.setColor(Color.RED);              System.out.println("Width: " + (dst.right - dst.left));              System.out.println("Height: " + (dst.bottom - dst.top));              System.out.println("Width: " + this.getDrawable().getIntrinsicWidth());              System.out.println("Height: " + this.getDrawable().getIntrinsicHeight());          }else{              set_LeftArea_Alpha();          }          canvas.drawRect(ChooseArea, mPaint);          mPaint.setColor(Color.BLUE);          canvas.drawRect(recLT, mPaint);          canvas.drawRect(recLB, mPaint);          canvas.drawRect(recRT, mPaint);             canvas.drawRect(recRB, mPaint);                    canvas.drawRect(leftRectL, leftAreaPaint);          canvas.drawRect(leftRectR, leftAreaPaint);          canvas.drawRect(leftRectT, leftAreaPaint);          canvas.drawRect(leftRectB, leftAreaPaint);                }            public void set_LeftArea_Alpha(){          leftRectL.set(dst.left, dst.top, ChooseArea.left, dst.bottom);          leftRectR.set(ChooseArea.right,dst.top,dst.right,dst.bottom);          leftRectT.set(ChooseArea.left, dst.top, ChooseArea.right, ChooseArea.top);          leftRectB.set(ChooseArea.left,ChooseArea.bottom,ChooseArea.right,dst.bottom);      }   }
View Code

 

 

播放幻灯片浏览图片再说明:

使用两个全局变量:

public String[] myImageNames;   //所有的图片的名字

public int ImageNameId = 0;     //图片编号

public String picfolderPath;    //实际上是 文件夹 的路径

开个线程,每3秒显示一张图片:

ImagePath = picfolderPath + File.separator + myImageNames[ImageNameId];

ImageNameId++;

public String picfolderPath;    //实际上是 文件夹 的路径  public String[] myImageNames;   //所有的图片的名字public int ImageNameId = 0;     //图片编号public String ImagePath ;       //图片的路径is = (ImageSwitcher) findViewById(R.id.slideshow_switcher);is.setFactory(this);is.setInAnimation(AnimationUtils.loadAnimation(this,android.R.anim.fade_in));is.setOutAnimation(AnimationUtils.loadAnimation(this,android.R.anim.fade_out));Runnable runnable=new Runnable() { //采用Handler的postDelayed(Runnable, long)方法 计时     @Override     public void run() {      // TODO Auto-generated method stub          if(ImageNameId < myImageNames.length)      {       is.reset();       ImagePath = picfolderPath + File.separator + myImageNames[ImageNameId];       ImageNameId++;       getSampledBitmap(ImagePath);                   }      else if(ImageNameId ==myImageNames.length)      {       is.reset();       ImageNameId = 0; //重置 ImageNameId,实现循环播放       ImagePath = picfolderPath + File.separator + myImageNames[ImageNameId];       ImageNameId++;       getSampledBitmap(ImagePath);                   }             //handler.removeCallbacks(runnable);//停止计时器       //handler.postDelayed(this, 3000);//3秒时间间隔             } };
View Code

 

Camera图片特效处理综述(Bitmap的Pixels处理、Canvas/paint的drawBitmap处理、旋转图片、裁截图片、播放幻灯片浏览图片<线程固定时间显示一张>)