android 以不规则图片为边框切割另外图片
转自:http://blog.sina.com.cn/s/blog_474928c90101dkvf.html
最近工作上遇到了一个将一个图片按照相框进行裁剪的问题,花了一个下午研究了下,在此整理一下,以便后用。
+ =
(相片) (相框) (结果图)
一个按照边框裁剪的类,因为相框通体为蓝色,只是不同区域的透明度不同,所以,选用了根据透明度来筛选边界上的点的方法。
另外,这个类也提供了判断一个点是否是在相框内部的方法:
和当前像素点同一水平线上的各点,假如左右两侧均有相框蓝色边界上的点的话,并且当前点不在边框上则认为当前点在相框的内部。
反之,则认为当前点在相框的外部。
package com.example.test_filter; import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Bitmap.Config; public class AlphaFilter implements Filter{ public static final int INSIDE_MODE = 0; public static final int EDGE_MODE = 1; public static final int OUTSIDE_MODE = 2; public int findNonOpaque(int x, int y, int width, int height, int[] srcPixels) { if(width < height) { return findNonOpaqueByX(x, y, width, height, srcPixels); } else { return findNonOpaqueByY(x, y, width, height, srcPixels); } } /* * 横向检测左右两侧边界 */ public int findNonOpaqueByX(int x, int y, int width, int height, int[] srcPixels) { int mode = OUTSIDE_MODE; //当前点左右两侧均有边界点出现,则认为当前点在内部或者边框中 if(findNonOpaqueByXLeft(x, y, width, height, srcPixels) && findNonOpaqueByXRight(x, y, width, height, srcPixels)) { mode = INSIDE_MODE; } int pos = y*width+x; if(isMatch(pos, srcPixels)) { mode = EDGE_MODE; } return mode; } /* * 检测与当前点y坐标相同的左侧各点是否有边界存在 */ public boolean findNonOpaqueByXLeft(int x, int y, int width, int height, int[] srcPixels) { for(int i=0; i < x; i++) { int pos = y*width + i; if(isMatch(pos, srcPixels)) { return true; } } return false; } /* * 检测与当前点y坐标相同的右侧各点是否有边界存在 */ public boolean findNonOpaqueByXRight(int x, int y, int width, int height, int[] srcPixels) { for(int i= x+1; i < width; i++) { int pos = y*width + i; if(isMatch(pos, srcPixels)) { return true; } } return false; } /* * 纵向检测上下两侧的边界 */ public int findNonOpaqueByY(int x, int y, int width, int height, int[] srcPixels) { int mode = OUTSIDE_MODE; //当前点上下两侧均有边界点出现,则认为当前点在内部或者边框中 if(findNonOpaqueByYTop(x, y, width, height, srcPixels) && findNonOpaqueByYBottom(x, y, width, height, srcPixels)) { mode = INSIDE_MODE; } int pos = y*width+x; if(isMatch(pos, srcPixels)) { mode = EDGE_MODE; } return mode; } /* * 检测与当前点x坐标相同的上方各点是否有边界存在 */ public boolean findNonOpaqueByYTop(int x, int y, int width, int height, int[] srcPixels) { for(int i=0; i < y; i++) { int pos = i*width + x; if(isMatch(pos, srcPixels)) { return true; } } return false; } /* * 检测与当前点x坐标相同的下方各点是否有边界存在 */ public boolean findNonOpaqueByYBottom(int x, int y, int width, int height, int[] srcPixels) { for(int i=y+1; i < height; i++) { int pos = i*width + x; if(isMatch(pos, srcPixels)) { return true; } } return false; } public boolean isMatch(int pos, int[]srcPixels) { int color = srcPixels[pos]; int alpha = Color.alpha(color); //检测是否是边界,针对背景图片选用透明度进行过滤 if(alpha >= 94 && alpha < 255) { return true; } return false; } /** * 图片效果叠加 * @param bmp 要裁剪的图片 * @param filter 边框 * @return */ public Bitmap overlay(Bitmap bmp, Bitmap filter) { int width = bmp.getWidth(); int height = bmp.getHeight(); Bitmap overlay = filter; Bitmap bitmap = Bitmap.createBitmap(width, height, Config.ARGB_4444); bitmap.setHasAlpha(true); // 对边框图片进行缩放 int w = overlay.getWidth(); int h = overlay.getHeight(); float scaleX = width * 1F / w; float scaleY = height * 1F / h; Matrix matrix = new Matrix(); matrix.postScale(scaleX, scaleY); Bitmap overlayCopy = Bitmap.createBitmap(overlay, 0, 0, w, h, matrix, true); int[] srcPixels = new int[width * height]; int[] layPixels = new int[width * height]; bmp.getPixels(srcPixels, 0, width, 0, 0, width, height); overlayCopy.getPixels(layPixels, 0, width, 0, 0, width, height); int pos = 0; for (int i = 0; i < height; i++) { for (int k = 0; k < width; k++) { pos = i * width + k; int mode = findNonOpaque(k, i, width, height, layPixels); if(mode == INSIDE_MODE) { srcPixels[pos] = srcPixels[pos]; continue; } else if(mode == EDGE_MODE){ srcPixels[pos] = layPixels[pos]; } else{ srcPixels[pos] = 0; continue; } } } bitmap.setPixels(srcPixels, 0, width, 0, 0, width, height); return bitmap; } } package com.example.test_filter; import android.os.AsyncTask; import android.os.Bundle; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.widget.ImageView; public class MainActivity extends Activity { ImageView filter; AlphaFilter alphaFilter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); filter = (ImageView) findViewById(R.id.filter); alphaFilter = new AlphaFilter(); } @Override protected void onResume() { Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.album_photo_0); Bitmap frame = BitmapFactory.decodeResource(getResources(), R.drawable.first_album_frame); new BitmapFilter().execute(bitmap, frame); super.onResume(); } class BitmapFilter extends AsyncTask<Bitmap, Bitmap, Bitmap> { @Override protected Bitmap doInBackground(Bitmap... params) { Bitmap bitmap = alphaFilter.overlay(params[0], params[1]); return bitmap; } @Override protected void onPostExecute(Bitmap result) { filter.setImageBitmap(result); super.onPostExecute(result); } } }