android以不規則圖片為邊框,切割另外的圖片

yangxi_001發表於2014-07-13

轉自:http://blog.csdn.net/ctpxyza/article/details/11094655

最近工作上遇到了一個將一個圖片按照相框進行裁剪的問題,花了一個下午研究了下,在此整理一下,以便後用。


          +            =     

   (相片)                                              (相框)                                             (結果圖)

一個按照邊框裁剪的類,因為相框通體為藍色,只是不同區域的透明度不同,所以,選用了根據透明度來篩選邊界上的點的方法。

另外,這個類也提供了判斷一個點是否是在相框內部的方法:
和當前畫素點同一水平線上的各點,假如左右兩側均有相框藍色邊界上的點的話,並且當前點不在邊框上則認為當前點在相框的內部
反之,則認為當前點在相框的外部。
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);
        }
        
        
    }
}

相關文章