您的位置:首页 > 移动开发 > Android开发

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

2014-07-27 22:26 706 查看


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





暂时还未有时间开发这效果,所以先贴出来。

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



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

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

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

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

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

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

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



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

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

[java] view
plaincopy

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;

}

}

};

}

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

[html] view
plaincopy

<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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐