将叠加(图像滤镜)应用于位图

时间:2012-01-06 20:30:20

标签: android bitmap png overlay android-camera

我正在尝试从相机意图中捕获图像,然后在其上应用图像过滤器。详细说明图像将是由相机捕获的图像,并且图像过滤器将作为png文件在资源中可用。我可以将滤镜叠加在原始图像的顶部。但是,一旦覆盖,原始图像“几乎”不可见(这意味着过滤器实际上堆叠在原始图像上而不仅仅是替换它)。我有几张图片来说明我的问题。第一张图片是在Photoshop中 - 当我在图像上面放置一个滤镜时,它似乎很好。第二个图像是由下面引用的代码生成的 - 您可以清楚地看到滤镜效果丢失。有人会知道为什么会发生这样的事情。我在这里错过了一些逻辑吗?

Filterd Image - Photoshop

Filtered Image - via code

以下是我的代码。如果您发现此处缺少任何最佳做法,我深表歉意。我最初试图测试代码:

mPictureView = (ImageView) findViewById(R.id.pictureView);
filterButton = (Button) findViewById(R.id.filter_button1);

// define the threshold fro scaling the image
private final double SCALE_THRESHOLD = 6.0;

// acquire the bitmap (photo captured) from the Camera Intent - the uri is 
// passed from a previous activity that accesses the camera and the current 
// activity is used to display the bitmap
Uri imageUri = getIntent().getData();
Bitmap imageBitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);

// set the imageView in the current activity to display the picture retrieved 
// from the camera
mPictureView.setImageBitmap(imageBitmap);

// get the dimensions of the original bitmap
int photoWidth = imageBitmap.getWidth();
int photoHeight = imageBitmap.getHeight();

filterButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    // set the options
    Options options = new BitmapFactory.Options();
    options.inScaled = false;
    options.inPreferredConfig = Bitmap.Config.ARGB_8888;

    // get the image (png file) filter from resources using the options
    Bitmap filter = BitmapFactory.decodeResource(getResources(), R.drawable.colorful_filter,options);

    // create a scaled copy of the filter
    Bitmap filtercopy = Bitmap.createScaledBitmap(filter, (int)(photoWidth/SCALE_THRESHOLD,(int)(photoHeight/SCALE_THRESHOLD), true);

    // recycle the used bitmap
    filter.recycle();
    filter = null;

    // get a scaled, mutable copy of the orginial image 
    Bitmap imagecopy = Bitmap.createScaledBitmap(imageBitmap,(int)(photoWidth/SCALE_THRESHOLD), (int)(photoHeight/SCALE_THRESHOLD),true);

    // recycle the used bitmap      
    imageBitmap.recycle();
    imageBitmap = null;


    Paint paint = new Paint();
    paint.setAntiAlias(true);

    //paint.setAlpha(230); - if a discrete value is set, then the image beneath 
    // the filter is visible. But, I don't understand why I need to do this. 
    // Besides, that reduces the efficacy of the filter

    // create a canvas with the original image as the underlying image      
    Canvas canvas = new Canvas(imagecopy);
    // now, draw the filter on top of the bitmap
    canvas.drawBitmap(filtercopy, 0, 0, paint);

    // recycle the used bitmap              
    filtercopy.recycle();
    filtercopy = null;

    //set the filtered bitmap as the image
    mPictureView.setImageBitmap(imagecopy);

}

编辑1:在Joru提供的文章的帮助下,我能够取得一些进展。问题似乎是混合2位图。在我拥有的情况下,drawBitmap方法只会在另一个上绘制一个位图。以下代码行实际上将尝试混合2位图。我还附上了描绘我进步的图像。现在,底层位图显而易见:

paint.setXfermode(new PorterDuffXfermode(Mode.MULTIPLY));    

在达到所需的输出之前,我还需要玩一段时间。 Color Filter - Revisited

1 个答案:

答案 0 :(得分:2)

你可以尝试一些事情:

Bitmap new = old.copy(Config.ARGB_8888, true);

确保您从MediaStore打开的位图采用该格式。如果不是,那很可能会导致您的问题。