http://www.myexception.cn/image/1255520.html
Adnroid上的簡單圖像合成類——PorterDuffXfermode
圖像合成,是将兩幅退昂放在一起的動作,它使得我們能夠同時看到兩幅圖像的特征。
我們可以首先在Canvas對象上繪制一個位圖對象,然後再相同的Canvas對象上繪制第二個位圖對象的方式來實作合成。不過這裡在繪制第二幅圖像的時候,需要在Paint對象上指定一個過渡模式(Xfermode)。
可用作過渡模式的類集合都繼承自Xfermode基類,而其中包括一個成為PorterDuffXfermode的類。PorterDuffXfermode因Thomas Porter和Tom Duff而得名,他們于1984年在ACM SIGGRAPH計算機圖形學出版物上發表了題為“Compositing digital images”(合成數字圖像)的文章,詳細介紹了一系列不同的規則,用于彼此重疊的繪制圖像。
在Android的PorterDuff.Mode類中列舉了他們制定的規則:
android.graphics.PorterDuff.Mode.CLEAR: 所繪制不會送出到畫布上
android.graphics.PorterDuff.Mode.SRC:隻繪制源圖像
android.graphics.PorterDuff.Mode.DST:隻繪制目标圖像
android.graphics.PorterDuff.Mode.DST_OVER:在源圖像的頂部繪制目标圖像
android.graphics.PorterDuff.Mode.DST_IN:隻在源圖像和目标圖像相交的地方繪制目标圖像
android.graphics.PorterDuff.Mode.DST_OUT:隻在源圖像和目标圖像不相交的地方繪制目标圖像
android.graphics.PorterDuff.Mode.DST_ATOP:在源圖像和目标圖像相交的地方繪制目标圖像,在不相交的地方繪制源圖像
android.graphics.PorterDuff.Mode.SRC_OVER:在目标圖像的頂部繪制源圖像
android.graphics.PorterDuff.Mode.SRC_IN:隻在源圖像和目标圖像相交的地方繪制源圖像
android.graphics.PorterDuff.Mode.SRC_OUT:隻在源圖像和目标圖像不相交的地方繪制源圖像
android.graphics.PorterDuff.Mode.SRC_ATOP:在源圖像和目标圖像相交的地方繪制源圖像,在不相交的地方繪制目标圖像
android.graphics.PorterDuff.Mode.XOR:在源圖像和目标圖像重疊之外的任何地方繪制他們,而在不重疊的地方不繪制任何内容
android.graphics.PorterDuff.Mode.LIGHTEN:獲得每個位置上兩幅圖像中最亮的像素并顯示
android.graphics.PorterDuff.Mode.DARKEN:獲得每個位置上兩幅圖像中最暗的像素并顯示
android.graphics.PorterDuff.Mode.MULTIPLY:将每個位置的兩個像素相乘,除以255,然後使用該值建立一個新的像素進行顯示。結果顔色=頂部顔色*底部顔色/255
android.graphics.PorterDuff.Mode.SCREEN:反轉每個顔色,執行相同的操作(将他們相乘并除以255),然後再次反轉。結果顔色=255-(((255-頂部顔色)*(255-底部顔色))/255)
以下是使用的範例源碼:
public class MainActivity extends Activity implements OnClickListener
{
static final int PICKED_ONE = 0;
static final int PICKED_TWO = 1;
boolean onePicked = false;
boolean twoPicked = false;
ImageView compositeImageView;
Button choosePicture1, choosePicture2;
Bitmap bmp1, bmp2;
Canvas canvas;
Paint paint;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
compositeImageView = (ImageView) findViewById(R.id.ChosenImageView);
choosePicture1 = (Button) findViewById(R.id.ChoosePictureButton1);
choosePicture2 = (Button) findViewById(R.id.ChoosePictureButton2);
choosePicture1.setOnClickListener(this);
choosePicture2.setOnClickListener(this);
}
@Override
public void onClick(View v)
{
// TODO Auto-generated method stub
int which = -1;
if (v == choosePicture1)
{
which = PICKED_ONE;
} else
{
which = PICKED_TWO;
}
Intent choosePictureIntent = new Intent(Intent.ACTION_PICK,
Media.EXTERNAL_CONTENT_URI);
startActivityForResult(choosePictureIntent, which);
}
private Bitmap loadBitmap(Uri imageFileUri)
{
Display currentDisplay = getWindowManager().getDefaultDisplay();
int dw = currentDisplay.getWidth();
int dh = currentDisplay.getHeight();
Bitmap returnBmp = Bitmap.createBitmap(dw, dh, Config.ARGB_4444);
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inJustDecodeBounds = true;
try
{
returnBmp = BitmapFactory.decodeStream(getContentResolver()
.openInputStream(imageFileUri), null, bmpFactoryOptions);
} catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
int heightRatio = (int) Math.ceil(bmpFactoryOptions.outHeight
/ (float) dh);
int widthRatio = (int) Math.ceil(bmpFactoryOptions.outWidth
/ (float) dw);
if (heightRatio > 1 && widthRatio > 1)
{
if (heightRatio > widthRatio)
{
bmpFactoryOptions.inSampleSize = heightRatio;
} else
{
bmpFactoryOptions.inSampleSize = widthRatio;
}
}
bmpFactoryOptions.inJustDecodeBounds = false;
try
{
returnBmp = BitmapFactory.decodeStream(getContentResolver()
.openInputStream(imageFileUri), null, bmpFactoryOptions);
} catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return returnBmp;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK)
{
Uri imageFileUri = data.getData();
if (requestCode == PICKED_ONE)
{
bmp1 = loadBitmap(imageFileUri);
onePicked = true;
} else
{
bmp2 = loadBitmap(imageFileUri);
twoPicked = true;
}
if (onePicked && twoPicked)
{
Bitmap drawingBitmap = Bitmap.createBitmap(bmp1.getWidth(),
bmp1.getHeight(), bmp1.getConfig());
canvas = new Canvas(drawingBitmap);
paint = new Paint();
canvas.drawBitmap(bmp1, 0, 0, paint);
paint.setXfermode(new PorterDuffXfermode(
android.graphics.PorterDuff.Mode.DARKEN));
canvas.drawBitmap(bmp2, 0, 0, paint);
compositeImageView.setImageBitmap(drawingBitmap);
}
}
}
}