国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

android實現圖片橡皮擦和快速染色功能

2019-10-21 21:32:38
字體:
來源:轉載
供稿:網友

本文為大家分享了android實現圖片橡皮擦和快速染色的具體代碼,供大家參考,具體內容如下

源碼地址:Eraselmg

1.染色

     關于染色部分,可以分別設置調整畫筆的大小和畫筆的透明度,畫筆已經設置了模糊效果。畫筆的特效可以調整下面一行代碼:

android,圖片橡皮擦,快速染色

2.橡皮擦

  橡皮擦的實現用了兩個canvas,一個臨時的,一個是作用在ImageTouchView上顯示的,代碼里面有注釋,這里不再詳細介紹。

3.功能展示:

原圖:

android,圖片橡皮擦,快速染色

畫筆設置界面:

android,圖片橡皮擦,快速染色

(1)畫筆大小為32,透明度為255(不透明)。如下圖:

android,圖片橡皮擦,快速染色

(2)畫筆大小為32,透明度為10,如下圖:

android,圖片橡皮擦,快速染色

融合的效果跟畫筆的透明度有關系,也跟背景圖片的相應區域顏色有關,所以透明度的值自行調整得出滿意效果。

(3)擦除

擦除前圖像:

android,圖片橡皮擦,快速染色

部分擦除后:

android,圖片橡皮擦,快速染色

4.Bitmap處理相關的類BitmapUtils:

package com.jiangjie.utils; import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import android.content.Context;import android.content.res.Resources;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Matrix;import android.graphics.Paint;import android.graphics.Rect;import android.graphics.Bitmap.Config;public class BitmapUtils {   /**  * 縮放圖片  */ public static void bitmapScale(Bitmap baseBitmap, Paint paint, float x, float y) {  // 因為要將圖片放大,所以要根據放大的尺寸重新創建Bitmap  Bitmap scaleBitmap = Bitmap.createBitmap(    (int) (baseBitmap.getWidth() * x),    (int) (baseBitmap.getHeight() * y), baseBitmap.getConfig());  Canvas canvas = new Canvas(scaleBitmap);  // 初始化Matrix對象  Matrix matrix = new Matrix();  // 根據傳入的參數設置縮放比例  matrix.setScale(x, y);  // 根據縮放比例,把圖片draw到Canvas上  canvas.drawBitmap(baseBitmap, matrix,paint); }  /**  * 圖片旋轉  */ public static void bitmapRotate(Bitmap baseBitmap, Paint paint,float degrees) {  // 創建一個和原圖一樣大小的圖片  Bitmap afterBitmap = Bitmap.createBitmap(baseBitmap.getWidth(),    baseBitmap.getHeight(), baseBitmap.getConfig());  Canvas canvas = new Canvas(afterBitmap);  Matrix matrix = new Matrix();  // 根據原圖的中心位置旋轉  matrix.setRotate(degrees, baseBitmap.getWidth() / 2,    baseBitmap.getHeight() / 2);  canvas.drawBitmap(baseBitmap, matrix, paint); }  /**  * 圖片移動  */ public static void bitmapTranslate(Bitmap baseBitmap, Paint paint, float dx, float dy) {  // 需要根據移動的距離來創建圖片的拷貝圖大小  Bitmap afterBitmap = Bitmap.createBitmap(    (int) (baseBitmap.getWidth() + dx),    (int) (baseBitmap.getHeight() + dy), baseBitmap.getConfig());  Canvas canvas = new Canvas(afterBitmap);  Matrix matrix = new Matrix();  // 設置移動的距離  matrix.setTranslate(dx, dy);  canvas.drawBitmap(baseBitmap, matrix, paint); }  /**  * 傾斜圖片  */ public static void bitmapSkew(Bitmap baseBitmap, Paint paint, float dx, float dy) {  // 根據圖片的傾斜比例,計算變換后圖片的大小,  Bitmap afterBitmap = Bitmap.createBitmap(baseBitmap.getWidth()    + (int) (baseBitmap.getWidth() * dx), baseBitmap.getHeight()    + (int) (baseBitmap.getHeight() * dy), baseBitmap.getConfig());  Canvas canvas = new Canvas(afterBitmap);  Matrix matrix = new Matrix();  // 設置圖片傾斜的比例  matrix.setSkew(dx, dy);  canvas.drawBitmap(baseBitmap, matrix, paint); }  public static Bitmap decodeFromResource(Context context, int id) {  Resources res = context.getResources();  Bitmap bitmap = BitmapFactory.decodeResource(res,id).copy(Bitmap.Config.ARGB_8888, true);  return bitmap; }   /**  * 保存圖片到SD卡  */ public static void saveToSdCard(String path, Bitmap bitmap) { if (null != bitmap && null != path && !path.equalsIgnoreCase("")) { try { File file = new File(path); FileOutputStream outputStream = null; //創建文件,并寫入內容 outputStream = new FileOutputStream(new File(path), true); bitmap.compress(Bitmap.CompressFormat.PNG, 30, outputStream); outputStream.flush(); outputStream.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }  /**  * 復制bitmap  */ public static Bitmap duplicateBitmap(Bitmap bmpSrc, int width, int height) { if (null == bmpSrc) { return null; }  int bmpSrcWidth = bmpSrc.getWidth(); int bmpSrcHeight = bmpSrc.getHeight();  Bitmap bmpDest = Bitmap.createBitmap(width, height, Config.ARGB_8888); if (null != bmpDest) { Canvas canvas = new Canvas(bmpDest); Rect viewRect = new Rect(); final Rect rect = new Rect(0, 0, bmpSrcWidth, bmpSrcHeight); if (bmpSrcWidth <= width && bmpSrcHeight <= height) { viewRect.set(rect); } else if (bmpSrcHeight > height && bmpSrcWidth <= width) { viewRect.set(0, 0, bmpSrcWidth, height); } else if (bmpSrcHeight <= height && bmpSrcWidth > width) { viewRect.set(0, 0, width, bmpSrcWidth); } else if (bmpSrcHeight > height && bmpSrcWidth > width) { viewRect.set(0, 0, width, height); } canvas.drawBitmap(bmpSrc, rect, viewRect, null); }  return bmpDest; }  /**  * 復制bitmap  */ public static Bitmap duplicateBitmap(Bitmap bmpSrc) { if (null == bmpSrc) { return null; }  int bmpSrcWidth = bmpSrc.getWidth(); int bmpSrcHeight = bmpSrc.getHeight();  Bitmap bmpDest = Bitmap.createBitmap(bmpSrcWidth, bmpSrcHeight, Config.ARGB_8888); if (null != bmpDest) { Canvas canvas = new Canvas(bmpDest); final Rect rect = new Rect(0, 0, bmpSrcWidth, bmpSrcHeight);  canvas.drawBitmap(bmpSrc, rect, rect, null); }  return bmpDest; }  /**  * bitmap轉字節碼  */ public static byte[] bitampToByteArray(Bitmap bitmap) { byte[] array = null; try { if (null != bitmap) { ByteArrayOutputStream os = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 100, os); array = os.toByteArray(); os.close(); } } catch (IOException e) { e.printStackTrace(); }  return array; }  /**  * 字節碼轉bitmap  */ public static Bitmap byteArrayToBitmap(byte[] array) { if (null == array) { return null; }  return BitmapFactory.decodeByteArray(array, 0, array.length); } }

5.圖像旋轉,縮放,橡皮擦和染色功能如下:

package com.jiangjie.ps; import com.jiangjie.utils.PaintConstants; import android.content.Context;import android.graphics.Bitmap;import android.graphics.Bitmap.Config;import android.graphics.BlurMaskFilter;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Matrix;import android.graphics.Paint;import android.graphics.Path;import android.graphics.PointF;import android.graphics.PorterDuff.Mode;import android.graphics.PorterDuffXfermode;import android.graphics.RectF;import android.graphics.drawable.BitmapDrawable;import android.util.AttributeSet;import android.util.DisplayMetrics;import android.util.FloatMath;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.widget.ImageView; public class ImageTouchView extends ImageView{ public Matrix matrix = new Matrix();  Matrix savedMatrix = new Matrix(); /** 屏幕的分辨率*/ private DisplayMetrics dm; /** 當前模式*/ int mode = PaintConstants.MODE.NONE;  /** 存儲float類型的x,y值,就是你點下的坐標的X和Y*/ PointF prev = new PointF(); PointF curPosition = new PointF(); PointF mid = new PointF(); float dist = 1f;  float oldRotation = 0;  float oldDistX = 1f; float oldDistY = 1f;  /**位圖對象*/ private Bitmap bitmap = null; private Paint paint; private Context context;  private Path path; private Path tempPath; //定義一個內存中的圖片,該圖片將作為緩沖區 Bitmap cacheBitmap = null;  //定義cacheBitmap上的Canvas對象 Canvas cacheCanvas = null; private Paint cachePaint = null;  private String TAG = "APP";  int x = 0;  int y = 0;    public ImageTouchView(Context context) { super(context); }  public ImageTouchView(Context context, AttributeSet attrs) { super(context, attrs); this.context = context; Log.i(TAG, "ImageTouchView(Context context, AttributeSet attrs)=>");  setupView(); }  @Override protected void onDraw(Canvas canvas) {  super.onDraw(canvas);  if(mode == PaintConstants.MODE.COLORING){ canvas.drawPath(tempPath, paint); }  }  public void setupView(){  //獲取屏幕分辨率,需要根據分辨率來使用圖片居中 dm = getContext().getResources().getDisplayMetrics(); //根據MyImageView來獲取bitmap對象 BitmapDrawable bd = (BitmapDrawable)this.getDrawable(); if(bd != null){ bitmap = bd.getBitmap(); // bitmap = setBitmapAlpha(bitmap, 100); center(true, true); }  setCoverBitmap(bitmap); this.setImageMatrix(matrix);  this.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { Matrix matrixTemp = new Matrix(); matrixTemp.set(matrix); //view的觸摸坐標的轉換 matrixTemp.invert(matrixTemp); Log.i(TAG, "Touch screen.");  switch (event.getAction() & MotionEvent.ACTION_MASK) { // 主點按下 case MotionEvent.ACTION_DOWN:  savedMatrix.set(matrix);  prev.set(event.getX(), event.getY());   float[] pointPrevInit = new float[]{prev.x, prev.y};  matrixTemp.mapPoints(pointPrevInit);  path.moveTo(pointPrevInit[0], pointPrevInit[1]);  tempPath.moveTo(event.getX(), event.getY());   mode = PaintConstants.MODE.DRAG;  Log.i(TAG, "ACTION_DOWN=>.");  break;  // 副點按下 case MotionEvent.ACTION_POINTER_DOWN:  dist = spacing(event);  oldRotation = rotation(event);   oldDistX = spacingX(event);  oldDistY = spacingY(event);  // 如果連續兩點距離大于10,則判定為多點模式  if (spacing(event) > 10f) {  savedMatrix.set(matrix);  midPoint(mid, event);  mode = PaintConstants.MODE.ZOOM;  }  break; case MotionEvent.ACTION_UP:  Log.i(TAG, "ACTION_UP=>.");  if(mode == PaintConstants.MODE.COLORING){  cachePaint.setColor(PaintConstants.PEN_COLOR);  cachePaint.setStrokeWidth(PaintConstants.PEN_SIZE);  cachePaint.setAlpha(PaintConstants.TRANSPARENT);   cachePaint.setMaskFilter(new BlurMaskFilter(5, PaintConstants.BLUR_TYPE));    cacheCanvas.drawPath(path, cachePaint);  path.reset();  tempPath.reset();  }  break;  case MotionEvent.ACTION_POINTER_UP:  mode = PaintConstants.MODE.NONE;  break;  case MotionEvent.ACTION_MOVE:  if(!PaintConstants.SELECTOR.KEEP_IMAGE){  if (mode == PaintConstants.MODE.DRAG) {  matrix.set(savedMatrix);  matrix.postTranslate(event.getX() - prev.x, event.getY() - prev.y);  } else if (mode == PaintConstants.MODE.ZOOM) {  float rotation = (rotation(event) - oldRotation)/2;   float newDistX = spacingX(event);  float newDistY = spacingY(event);   float scaleX = newDistX-oldDistX;  float scaleY = newDistY-oldDistY;   float newDist = spacing(event);  if (newDist > 10f) {  matrix.set(savedMatrix);  float tScale = newDist / dist;  tScale = tScale>1?1+((tScale-1)/2):1-(1-tScale)/2;  if(PaintConstants.SELECTOR.KEEP_SCALE){   matrix.postScale(tScale, tScale, mid.x, mid.y);// 縮放   }else{   if(Math.abs(scaleX)>=Math.abs(scaleY)){   matrix.postScale(tScale, 1, mid.x, mid.y);// 縮放    }else{   matrix.postScale(1, tScale, mid.x, mid.y);// 縮放   }  }  if(PaintConstants.SELECTOR.HAIR_RURN)   matrix.postRotate(rotation, mid.x, mid.y);// 旋轉   }  }  }else{  float[] pointPrev = new float[]{prev.x, prev.y};  float[] pointStop= new float[]{event.getX(), event.getY()};    //view的觸摸坐標的轉換  matrixTemp.mapPoints(pointPrev);  matrixTemp.mapPoints(pointStop);    if(PaintConstants.SELECTOR.COLORING){  //染色功能  mode = PaintConstants.MODE.COLORING;  paint.reset();  paint = new Paint(Paint.DITHER_FLAG);  paint.setColor(Color.RED);  //設置畫筆風格  paint.setStyle(Paint.Style.STROKE);  paint.setStrokeWidth(1);  //反鋸齒  paint.setAntiAlias(true);  paint.setDither(true);   paint.setColor(PaintConstants.PEN_COLOR);  paint.setStrokeWidth(PaintConstants.PEN_SIZE);   path.quadTo(pointPrev[0],pointPrev[1],pointStop[0],pointStop[1]);  tempPath.quadTo(prev.x, prev.y,event.getX(), event.getY());    // 更新開始點的位置  prev.set(event.getX(), event.getY());   ImageTouchView.this.setImageBitmap(cacheBitmap);    }else if(PaintConstants.SELECTOR.ERASE){  //橡皮擦功能   mode = PaintConstants.MODE.ERASE;   paint.reset();  paint.setColor(Color.TRANSPARENT);  paint.setAntiAlias(false);  paint.setStyle(Paint.Style.STROKE);  paint.setStrokeWidth(16);  paint.setStrokeJoin(Paint.Join.ROUND);  paint.setStrokeCap(Paint.Cap.ROUND);  paint.setAlpha(0);   paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));  paint.setStrokeWidth(PaintConstants.ERASE_SIZE);   prev.set(event.getX(), event.getY());    cacheCanvas.drawLine(pointPrev[0],pointPrev[1],pointStop[0],pointStop[1], paint);  ImageTouchView.this.setImageBitmap(cacheBitmap);   }  } } ImageTouchView.this.setImageMatrix(matrix); invalidate();  return true; } }); }  /** * 橫向、縱向居中 */ protected void center(boolean horizontal, boolean vertical) { RectF rect = new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight());  float height = rect.height(); float width = rect.width();  float deltaX = 0, deltaY = 0;  if (vertical) { // 圖片小于屏幕大小,則居中顯示。大于屏幕,上方留空則往上移,下方留空則往下移 int screenHeight = dm.heightPixels; if (height < screenHeight) { deltaY = (screenHeight - height) / 2 - rect.top; } else if (rect.top > 0) { deltaY = -rect.top; } else if (rect.bottom < screenHeight) { deltaY = this.getHeight() - rect.bottom; } }  if (horizontal) { int screenWidth = dm.widthPixels; if (width < screenWidth) { deltaX = (screenWidth - width) / 2 - rect.left; } else if (rect.left > 0) { deltaX = -rect.left; } else if (rect.right < screenWidth) { deltaX = screenWidth - rect.right; } } matrix.postTranslate(deltaX, deltaY); }   private float spacingX(MotionEvent event) {  float x = event.getX(0) - event.getX(1);  return x; }  private float spacingY(MotionEvent event) {  float y = event.getY(0) - event.getY(1);  return y;  }   // 取旋轉角度  private float rotation(MotionEvent event) {  double delta_x = (event.getX(0) - event.getX(1));  double delta_y = (event.getY(0) - event.getY(1));  double radians = Math.atan2(delta_y, delta_x);  return (float) Math.toDegrees(radians);  }   /** * 兩點的距離 */ private float spacing(MotionEvent event) { float x = event.getX(0) - event.getX(1); float y = event.getY(0) - event.getY(1); return FloatMath.sqrt(x * x + y * y); }  /** * 兩點的中點 */ private void midPoint(PointF point, MotionEvent event) { float x = event.getX(0) + event.getX(1); float y = event.getY(0) + event.getY(1); point.set(x / 2, y / 2); }   /**  *  * @param bm  * @note set cover bitmap , which overlay on background.  */  private void setCoverBitmap(Bitmap bitmap) {  // setting paint  paint = new Paint();   cacheBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);  cacheCanvas = new Canvas(); cacheCanvas.setBitmap(cacheBitmap); cacheCanvas.drawBitmap( bitmap, 0, 0, null);   path = new Path(); tempPath = new Path();  //設置畫筆的顏色 cachePaint = new Paint(); //設置畫筆風格 cachePaint.setStyle(Paint.Style.STROKE); //反鋸齒 cachePaint.setAntiAlias(true); cachePaint.setStrokeJoin(Paint.Join.ROUND); cachePaint.setStrokeCap(Paint.Cap.ROUND); cachePaint.setXfermode(new PorterDuffXfermode(Mode.SRC_ATOP)); //設置畫筆模糊效果 cachePaint.setMaskFilter(new BlurMaskFilter(5, PaintConstants.BLUR_TYPE));  }  }

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 普定县| 广安市| 洪泽县| 准格尔旗| 桐城市| 营口市| 固始县| 绥棱县| 阳谷县| 庆城县| 安泽县| 藁城市| 邳州市| 上饶县| 东至县| 北安市| 彩票| 砚山县| 尉氏县| 禹城市| 铁岭市| 五指山市| 密山市| 巴东县| 德钦县| 佛山市| 平谷区| 海盐县| 云南省| 米林县| 获嘉县| 林州市| 罗田县| 宁波市| 北票市| 根河市| 江安县| 罗平县| 隆林| 黑山县| 深圳市|