暫時還未有時間開發這效果,是以先貼出來。
先貼一張效果圖,這是一張手機截屏:

左上方的風景圖:背景圖檔
右上方的人物圖:前景圖檔
左邊心型透明圖:相框圖檔
右邊心型黑色圖:蒙闆圖檔
功能:把前景圖應用蒙闆,添加相框效果,合成到後景圖上面:
結果就是下面的那張圖檔了。
還有一種是透明度漸變的,效果圖如下:
因為隻有透明度漸變,沒有相框。但實作上基本一樣。
下面是實作過程,直接貼代碼吧,其中寫了比較詳細的注釋。隻有一個檔案,如下:
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");
if(resultBitmap == null || resultBitmap.isRecycled()){
Log.e(TAG, "compose ERROR: resultBitmap is not valuable");
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);
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;
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"
</LinearLayout>
android:id="@+id/views2"
android:layout_below="@+id/views1"
android:id="@+id/frame"
android:id="@+id/mask"
<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_height="wrap_content"/>
</RelativeLayout>