中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

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

發布時間:2020-10-11 14:33:19 來源:腳本之家 閱讀:160 作者:愛折騰的貓 欄目:移動開發

本文為大家分享了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));
 
 } 
 
}

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

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

巴里| 贵南县| 综艺| 天峨县| 瓦房店市| 清流县| 文安县| 孝义市| 惠来县| 乐东| 扎兰屯市| 桐梓县| 新乐市| 太湖县| 手游| 金阳县| 余干县| 平利县| 双流县| 中西区| 靖州| 余江县| 滨海县| 周宁县| 宜良县| 隆子县| 永宁县| 双牌县| 龙岩市| 肃宁县| 山阴县| 崇信县| 衡水市| 海盐县| 阿鲁科尔沁旗| 蒙城县| 双桥区| 英山县| 临城县| 年辖:市辖区| 六枝特区|