title: Applying an overlay (image filter) to a Bitmap
body: <p>I am trying to capture an image from the camera intent and then apply an image filter on it. To elaborate the image would be an image captured by the camera and the image filter would be available in the resources as a png file. I am able to overlay the  filter on top of the original image. But, once overlay-ed the original image is 'almost' invisible (which means that the filter is infact being stacked on the original image and not merely replacing it). I have a couple of images to illustrate my problem. The first image was in Photoshop - when I placed a filter on top of an image, it seemed just fine. The second image is the produced by the code cited below - you can clearly see that the filter effect is missing. Would someone have a clue as to why something like this is occurring. Am I missing some logic here? </p>
  
  <p><img src="https://i.stack.imgur.com/1KlKq.png" alt="Filterd Image - Photoshop"></p>
  
  <p><img src="https://i.stack.imgur.com/06eD7.png" alt="Filtered Image - via code"></p>
  
  <p><strong>The following is the code that I have. I apologize if you find any best practices missing here. I am initially trying to test the code:</strong></p>
  
  <pre><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);
  
  }
  </code></pre>
  
  <p><strong>EDIT 1: I was able to make some progress with the help of the article that Joru has provided. The problem seems to be with blending of the 2 bitmaps. The method drawBitmap would just draw one bitmap over the other in the situation that I have. The following line of code will actually attempt to blend the 2 bitmaps. I have also attached an image which depicts my progress. The underlying bitmap is noticeably more visible now:</strong> </p>
  
  <pre><code>paint.setXfermode(new PorterDuffXfermode(Mode.MULTIPLY));    
  </code></pre>
  
  <p><strong>I have to still play around with it for some time, before achieving the desired output.</strong><img src="https://i.stack.imgur.com/DEHQH.png" alt="Color Filter - Revisited"></p>