Android相框合成图片抠图
2017-05-05 11:37
579 查看
近期公司有个需求,需要做一个照片加模板以及加相框支持拖拽,翻了翻资料实现一下,跟大家分享一下.
主要使用Android 下的PorterDuffXfermode-> 这个东西对于操作2D图像很强大
直接上代码
这就是扩展了一个ImageView控件,使用起来也很简单,只需要传入类型,原图,相框及模板(如果只是形状传入1个模板,如果是不规则相框则需要两个),大家可以在源代码里面看一下相框及模板的例子,这就不多说了.
CSDN源代码地址
主要使用Android 下的PorterDuffXfermode-> 这个东西对于操作2D图像很强大
直接上代码
/** * 合成图片 不规则图片 拖拽显示部分区域 */ public class AlbumImageView extends ImageView { public int ALBUM_IMAGE_TYPE = 0; //合成图片类型 public static final int ALBUM_IMAGE_SHAPE = 1001; // 图片类型: 形状 public static final int ALBUM_IMAGE_FRAME = 1002; // 图片类型: 带相框的高大上图片 private Bitmap[] bitmapMask = new Bitmap[2]; // 图片模板: 形状的只有1个 带相框的则有两个(一个是相框,一个是相框的阴影截取范围) private Bitmap src; // 原图片 private float xOffset = 0.f; // x轴偏移 private float yOffset = 0.f; //y轴偏移 private float downX = 0.0f; //手指所在x坐标 private float downY = 0.0f; //手指所在y坐标 public AlbumImageView(Context context, int image_type, Bitmap src, Bitmap[] bitmapMask, float xOffset, float yOffset) { super(context); this.ALBUM_IMAGE_TYPE = image_type; this.bitmapMask = bitmapMask; this.src = src; this.xOffset = xOffset; this.yOffset = yOffset; init(); } public AlbumImageView(Context context, AttributeSet attrs) { super(context, attrs); } /** * 初始化处理原图片 保证图片不能小于相框或形状 */ private void init() { if (src.getWidth() < bitmapMask[0].getWidth()) { //如果原图片宽小于模板宽 按照等比例拉伸原图片 Matrix matrix = new Matrix(); matrix.postScale((float) bitmapMask[0].getWidth() / (float) src.getWidth(), (float) bitmapMask[0].getWidth() / (float) src.getWidth()); src = Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), matrix, true); } if (src.getHeight() < bitmapMask[0].getHeight()) { //如果原图片高小于模板搞 按照等比例拉伸原图片 Matrix matrix2 = new Matrix(); matrix2.postScale((float) bitmapMask[0].getHeight() / (float) src.getHeight(), (float) bitmapMask[0].getHeight() / (float) src.getHeight()); src = Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), matrix2, true); } this.setImageBitmap(resolveBitmap(-xOffset, -yOffset)); //设置Bitmap } /** * 处理图片 合成图片 * * @param xOffset x轴偏移量 * @param yOffset y轴偏移量 * @return 返回合成之后的Bitmap */ private Bitmap resolveBitmap(float xOffset, float yOffset) { Bitmap bmp = Bitmap.createBitmap(bitmapMask[0].getWidth(), bitmapMask[0].getHeight(), Bitmap.Config.ARGB_4444); //用模板生成一个bmp Paint paint = new Paint(); //初始化画笔 if (ALBUM_IMAGE_TYPE == ALBUM_IMAGE_SHAPE) { paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP)); //PorterDuffXfermode算法 SRC_ATOP 取下层非交集部分与上层交集部分 Canvas canvas = new Canvas(bmp); canvas.drawBitmap(bitmapMask[0], 0, 0, null); // 画模板 canvas.drawBitmap(src, xOffset, yOffset, paint); //画原图 return bmp; } else { paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP)); //DST_ATOP 取上层非交集部分与下层交集部分 Canvas canvas = new Canvas(bmp); canvas.drawBitmap(bitmapMask[0], 0, 0, null); canvas.drawBitmap(src, xOffset, yOffset, paint); Bitmap result = Bitmap.createBitmap(bitmapMask[1].getWidth(), bitmapMask[1].getHeight(), Bitmap.Config.ARGB_4444); // 相框阴影部分图片 Canvas canvas1 = new Canvas(result); Paint paint1 = new Paint(); paint1.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT)); // 然后再画阴影部分 SRC_OUT 取上层非交集部分 抠出相框和图片 canvas1.drawBitmap(bitmapMask[1], 0, 0, null); canvas1.drawBitmap(bmp, 0, 0, paint1); bmp.recycle(); return result; } } @Override public boolean onTouchEvent(MotionEvent event) { Log.i("gxh", "aaa"); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: downX = event.getX(); downY = event.getY(); break; case MotionEvent.ACTION_MOVE: int offsetX = -((int) downX - (int) event.getX()); int offsetY = -((int) downY - (int) event.getY()); xOffset += offsetX; yOffset += offsetY; //判断是否滑到边界 if ((xOffset <= 0 && yOffset <= 0) && (src.getWidth() - Math.abs(xOffset) > bitmapMask[0].getWidth() && src.getHeight() - Math.abs(yOffset) > bitmapMask[0].getHeight())) { this.setImageBitmap(resolveBitmap(xOffset, yOffset)); } else { //else 里面判断xy某一坐标滑到边界 另一个坐标还得继续移动 否则会出现问题 if (xOffset > 0) { xOffset = 0; } if (yOffset > 0) { yOffset = 0; } if (src.getWidth() - Math.abs(xOffset) < bitmapMask[0].getWidth()) { xOffset = bitmapMask[0].getWidth() - src.getWidth(); } if (src.getHeight() - Math.abs(yOffset) < bitmapMask[0].getHeight()) { yOffset = bitmapMask[0].getHeight() - src.getHeight(); } setImageBitmap(resolveBitmap(xOffset, yOffset)); } downX = event.getX(); downY = event.getY(); break; } return true; } }
这就是扩展了一个ImageView控件,使用起来也很简单,只需要传入类型,原图,相框及模板(如果只是形状传入1个模板,如果是不规则相框则需要两个),大家可以在源代码里面看一下相框及模板的例子,这就不多说了.
public class MainActivity extends AppCompatActivity { Bitmap dog; Bitmap maskSecond; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); dog = BitmapFactory.decodeResource(this.getResources(), R.drawable.dog); final Bitmap mask = BitmapFactory.decodeResource(this.getResources(), maskkk); maskSecond = BitmapFactory.decodeResource(this.getResources(), R.drawable.masksecond); AlbumImageView img = new AlbumImageView(this, AlbumImageView.ALBUM_IMAGE_FRAME, dog, new Bitmap[]{mask, maskSecond}, 0, 0); setContentView(img); } }
CSDN源代码地址
相关文章推荐
- Android 图片合成:添加蒙板效果 不规则相框 透明度渐变效果的实现
- Android 图片合成:添加蒙板效果 不规则相框 透明度渐变效果的实现
- [Android] 给图像加入相框、圆形圆角显示图片、图像合成知识
- Android 图片合成:添加蒙板效果 不规则相框 透明度渐变效果的实现
- Android 图片合成:添加蒙板效果 不规则相框 透明度渐变效果的实现
- [Android] 给图像添加相框、圆形圆角显示图片、图像合成知识
- Android 图片合成:添加蒙板效果 不规则相框 透明度渐变效果的实现
- Android 图片合成:添加蒙板效果 不规则相框 透明度渐变效果的实现
- Android 图片合成:添加蒙板效果 不规则相框 透明度渐变效果的实现
- Android 图片合成:添加蒙板效果 不规则相框 透明度渐变效果的实现
- Android之图片处理(图片合成、图片圆角、图片翻转、图片缩放)
- Android图片合成
- Android PopupWindow,GridView,BaseAdapter以及图片合成综合案例
- android 图片处理(图片合成、图片圆角、图片翻转、图片缩放)
- Android:将数字画在图片上合成一张图的两种实现方法(一)
- Android图片的合成
- 在Android中的大图片合成-PNG(一) PNG格式详解
- android 文字图片合成
- Android图片的合成
- android 合成两张图片,上层图片设置透明度