For those who are using alpha in the original image.
I wrote this code in Koltin, the key point here is that if you have the alpha on your original image you need to multiply these channels. 
Koltin Version: 
    val width = this.width
    val imgData = IntArray(width)
    val maskData = IntArray(width)
    for(y in 0..(this.height - 1)) {
      this.getRGB(0, y, width, 1, imgData, 0, 1)
      mask.getRGB(0, y, width, 1, maskData, 0, 1)
      for (x in 0..(this.width - 1)) {
        val maskAlpha = (maskData[x] and 0x000000FF)/ 255f
        val imageAlpha = ((imgData[x] shr 24) and 0x000000FF) / 255f
        val rgb = imgData[x] and 0x00FFFFFF
        val alpha = ((maskAlpha * imageAlpha) * 255).toInt() shl 24
        imgData[x] = rgb or alpha
      }
      this.setRGB(0, y, width, 1, imgData, 0, 1)
    }
Java version (just translated from Kotlin)
    int width = image.getWidth();
    int[] imgData = new int[width];
    int[] maskData = new int[width];
    for (int y = 0; y < image.getHeight(); y ++) {
        image.getRGB(0, y, width, 1, imgData, 0, 1);
        mask.getRGB(0, y, width, 1, maskData, 0, 1);
        for (int x = 0; x < image.getWidth(); x ++) {
            //Normalize (0 - 1)
            float maskAlpha = (maskData[x] & 0x000000FF)/ 255f;
            float imageAlpha = ((imgData[x] >> 24) & 0x000000FF) / 255f;
            //Image without alpha channel
            int rgb = imgData[x] & 0x00FFFFFF;
            //Multiplied alpha
            int alpha = ((int) ((maskAlpha * imageAlpha) * 255)) << 24;
            //Add alpha to image
            imgData[x] = rgb | alpha;
        }
        image.setRGB(0, y, width, 1, imgData, 0, 1);
    }