Android 图片合成:添加蒙板效果 不规则相框 透明度渐变效果的实现

先贴一张效果图,这是一张手机截屏:


Android 图片合成:添加蒙板效果 不规则相框 透明度渐变效果的实现_第1张图片

左上方的风景图:背景图片

右上方的人物图:前景图片

左边心型透明图:相框图片

右边心型黑色图:蒙板图片


功能:把前景图应用蒙板,添加相框效果,合成到后景图上面:

结果就是下面的那张图片了。


还有一种是透明度渐变的,效果图如下:

Android 图片合成:添加蒙板效果 不规则相框 透明度渐变效果的实现_第2张图片

因为只有透明度渐变,没有相框。但实现上基本一样。


下面是实现过程,直接贴代码吧,其中写了比较详细的注释。只有一个文件,如下:

package com.example.androiddemo;


import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends Activity {

	private static final String TAG = "liuzw";
	
	private ImageView picBGView;
	private ImageView pictureView;
	private ImageView maskView;
	private ImageView frameView;
	private ImageView resultView;
	private Button startProcess;
	private Bitmap picBitmap;
	private Bitmap maskBitmap;
	private Bitmap frameBitmap;
	private Bitmap resultBitmap;
	private Bitmap fengjingBitmap;
	private Bitmap composedBitmap;
	
	private final int WITHOUT = -1;
	private static final int FRAME = 0;
	private static final int MASK = 1;
	
//	private int[] resIds = new int[]{		//斜框锯齿
//			R.drawable.pip_6_frame,
//			R.drawable.pip_6_frame_mask,
//	};
	
//	private int[] resIds = new int[]{		//胶条
//			R.drawable.pip_1_frame,
//			R.drawable.pip_1_frame_mask,
//	};
	
	private int[] resIds = new int[]{		//渐变
			WITHOUT,
			R.drawable.pip_2_frame_mask,
	};
	
//	private int[] resIds = new int[]{		//心形
//			R.drawable.pip_3_frame,
//			R.drawable.pip_3_frame_mask,
//	};
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		picBGView = (ImageView) findViewById(R.id.pic_bg);
		picBGView.setImageResource(R.drawable.fengjing);
		pictureView = (ImageView) findViewById(R.id.pic);
		pictureView.setImageResource(R.drawable.pip_test);
		maskView = (ImageView) findViewById(R.id.mask);
		maskView.setImageResource(resIds[MASK]);
		frameView = (ImageView) findViewById(R.id.frame);
		frameView.setImageResource(resIds[FRAME]);
		startProcess = (Button) findViewById(R.id.btnStart);
		startProcess.setOnClickListener(mListener);
		resultView = (ImageView) findViewById(R.id.showResult);
		
	}
	
	/**
	 * 获得前置照片
	 */
	private void getFrontPicture(){
		//蒙板的Bitmap
		if(maskBitmap == null || maskBitmap.isRecycled() && resIds[MASK] != WITHOUT){
			maskBitmap = BitmapFactory.decodeResource(this.getResources(), resIds[MASK]);
		}
		if(maskBitmap == null) return;
		
		//前置的原图,并将其缩放到跟蒙板大小一直
		if(picBitmap == null || picBitmap.isRecycled()){
			picBitmap = BitmapFactory.decodeResource(this.getResources(), R.drawable.pip_test);
			picBitmap = Bitmap.createScaledBitmap(picBitmap, maskBitmap.getWidth(), maskBitmap.getHeight(), false);
		}
		
		//相框的Bitmap
		if(frameBitmap == null || frameBitmap.isRecycled() && resIds[FRAME] != WITHOUT){
			frameBitmap = BitmapFactory.decodeResource(this.getResources(), resIds[FRAME]);
		}
		
		int w = maskBitmap.getWidth();
		int h = maskBitmap.getHeight();
		
		int edgeColor = maskBitmap.getPixel(1, 1);
		int centerColor = maskBitmap.getPixel(w/2, h/2);
		Log.d(TAG, "edgeColor = " + Integer.toHexString(edgeColor) + ", centerColor = " + Integer.toHexString(centerColor));
		
		if(resultBitmap == null){
			resultBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
		}
		
		//这是背景的风景图
		if(fengjingBitmap == null){
			fengjingBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.fengjing);
		}
		
		//前置相片添加蒙板效果
		int[] picPixels = new int[w*h];
		int[] maskPixels = new int[w*h];
		picBitmap.getPixels(picPixels, 0, w, 0, 0, w, h);
		maskBitmap.getPixels(maskPixels, 0, w, 0, 0, w, h);
		for(int i = 0; i < maskPixels.length; i++){
			if(maskPixels[i] == 0xff000000){
				picPixels[i] = 0;
			}else if(maskPixels[i] == 0){
				//donothing
			}else{
				//把mask的a通道应用与picBitmap
				maskPixels[i] &= 0xff000000;
				maskPixels[i] = 0xff000000 - maskPixels[i];	
				picPixels[i] &= 0x00ffffff;
				picPixels[i] |= maskPixels[i];
			}
		}
		
		//生成前置图片添加蒙板后的bitmap:resultBitmap
		resultBitmap.setPixels(picPixels, 0, w, 0, 0, w, h);
	}
	
	/**
	 * 图片合成
	 */
	private void compose(){
		if(fengjingBitmap == null || fengjingBitmap.isRecycled()){
			Log.e(TAG, "compose ERROR: fengjingBitmap is not valuable");
			return;
		}
		composedBitmap = Bitmap.createBitmap(fengjingBitmap.getWidth(), fengjingBitmap.getHeight(), Bitmap.Config.ARGB_8888);
		if(composedBitmap == null || composedBitmap.isRecycled()){
			Log.e(TAG, "compose ERROR: composedBitmap is not valuable");
			return;
		}
		if(resultBitmap == null || resultBitmap.isRecycled()){
			Log.e(TAG, "compose ERROR: resultBitmap is not valuable");
			return;
		}
		Canvas cv = new Canvas(composedBitmap);
		cv.drawBitmap(fengjingBitmap, 0, 0, null);
		cv.drawBitmap(resultBitmap, 100, 100, null);
		
		if(frameBitmap != null && !frameBitmap.isRecycled()){
			cv.drawBitmap(frameBitmap, 100, 100, null);
		}
		
		cv.save(Canvas.ALL_SAVE_FLAG);
		cv.restore();
		resultView.setImageBitmap(composedBitmap);
	}
	
	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		//释放资源
		resultView.setImageBitmap(null);
		if(picBitmap != null && !picBitmap.isRecycled()){
			picBitmap.recycle();
			picBitmap = null;
		}
		if(maskBitmap != null && !maskBitmap.isRecycled()){
			maskBitmap.recycle();
			maskBitmap = null;
		}
		if(frameBitmap != null && !frameBitmap.isRecycled()){
			frameBitmap.recycle();
			frameBitmap = null;
		}
		if(resultBitmap != null && !resultBitmap.isRecycled()){
			resultBitmap.recycle();
			resultBitmap = null;
		}
		if(fengjingBitmap != null && !fengjingBitmap.isRecycled()){
			fengjingBitmap.recycle();
			fengjingBitmap = null;
		}
		if(composedBitmap != null && !composedBitmap.isRecycled()){
			composedBitmap.recycle();
			composedBitmap = null;
		}
	}
	
	private OnClickListener mListener = new OnClickListener(){

		@Override
		public void onClick(View v) {
			// TODO Auto-generated method stub
			switch(v.getId()){
			case R.id.btnStart:
				getFrontPicture();
				compose();
				break;
			}
		}
		
	};
	
}

为了完整和方便参考,把布局文件也贴一下,如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffffff"
    tools:context=".MainActivity" >

    <LinearLayout 
        android:id="@+id/views1"
        android:layout_width="match_parent"
        android:layout_height="150dip"
        android:orientation="horizontal" >
        
         <ImageView 
            android:id="@+id/pic_bg"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1.0" />
         
        <ImageView 
            android:id="@+id/pic"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1.0" />
    </LinearLayout>
    
    <LinearLayout 
        android:id="@+id/views2"
        android:layout_below="@+id/views1"
        android:layout_width="match_parent"
        android:layout_height="150dip"
        android:orientation="horizontal" >
        
        
        <ImageView 
            android:id="@+id/frame"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1.0" />
        
        <ImageView 
            android:id="@+id/mask"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1.0" />
        
    </LinearLayout>

    <Button 
        android:id="@+id/btnStart"
        android:layout_below="@+id/views2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Start" />
    
    <ImageView 
        android:id="@+id/showResult"
        android:layout_below="@+id/btnStart"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    
</RelativeLayout>






你可能感兴趣的:(android,pip,图片合成,相框,透明度渐变)