代码之家  ›  专栏  ›  技术社区  ›  Zarkonnen

在Java中设置BuffereImage alpha掩码

  •  20
  • Zarkonnen  · 技术社区  · 17 年前

    我想通过应用alpha蒙版,从两者创建一个组合图像。我的谷歌浏览器让我失望。

    5 回复  |  直到 17 年前
        1
  •  22
  •   Meyer SQLRocker    10 年前

    我现在回答这个问题已经太迟了,但也许它对某些人来说是有用的。这是Michael Myers方法的一个更简单、更有效的版本:

    public void applyGrayscaleMaskToAlpha(BufferedImage image, BufferedImage mask)
    {
        int width = image.getWidth();
        int height = image.getHeight();
    
        int[] imagePixels = image.getRGB(0, 0, width, height, null, 0, width);
        int[] maskPixels = mask.getRGB(0, 0, width, height, null, 0, width);
    
        for (int i = 0; i < imagePixels.length; i++)
        {
            int color = imagePixels[i] & 0x00ffffff; // Mask preexisting alpha
            int alpha = maskPixels[i] << 24; // Shift blue to alpha
            imagePixels[i] = color | alpha;
        }
    
        image.setRGB(0, 0, width, height, imagePixels, 0, width);
    }
    

    与其他方法一样,它假定两个图像具有相同的尺寸。

        2
  •  12
  •   PhiLho    17 年前

    我最近玩了一点这个东西,把一个图像显示在另一个图像上,然后把一个图像淡入灰色。
    还可以使用透明遮罩遮罩图像(我以前的版本)。

    我拿了我的小测试程序,对它做了一些调整,以得到想要的结果。

    TestMask() throws IOException
    {
        m_images = new BufferedImage[3];
        m_images[0] = ImageIO.read(new File("E:/Documents/images/map.png"));
        m_images[1] = ImageIO.read(new File("E:/Documents/images/mapMask3.png"));
        Image transpImg = TransformGrayToTransparency(m_images[1]);
        m_images[2] = ApplyTransparency(m_images[0], transpImg);
    }
    
    private Image TransformGrayToTransparency(BufferedImage image)
    {
        ImageFilter filter = new RGBImageFilter()
        {
            public final int filterRGB(int x, int y, int rgb)
            {
                return (rgb << 8) & 0xFF000000;
            }
        };
    
        ImageProducer ip = new FilteredImageSource(image.getSource(), filter);
        return Toolkit.getDefaultToolkit().createImage(ip);
    }
    
    private BufferedImage ApplyTransparency(BufferedImage image, Image mask)
    {
        BufferedImage dest = new BufferedImage(
                image.getWidth(), image.getHeight(),
                BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2 = dest.createGraphics();
        g2.drawImage(image, 0, 0, null);
        AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.DST_IN, 1.0F);
        g2.setComposite(ac);
        g2.drawImage(mask, 0, 0, null);
        g2.dispose();
        return dest;
    }
    

    其余的只是在一个小的Swing面板中显示图像。
    请注意,遮罩图像为灰度级,黑色变为完全透明,白色变为完全不透明。

    虽然你已经解决了你的问题,但我想我可以分享我对这个问题的看法。它使用了一种稍微更具Java风格的方法,使用标准类来处理/过滤图像。

    至少,你还有选择!:-)

        3
  •  10
  •   pek    14 年前

    http://java.sun.com/javase/6/docs/api/java/awt/image/BufferedImage.html

    final int width = image.getWidth();
    int[] imgData = new int[width];
    int[] maskData = new int[width];
    
    for (int y = 0; y < image.getHeight(); y++) {
        // fetch a line of data from each image
        image.getRGB(0, y, width, 1, imgData, 0, 1);
        mask.getRGB(0, y, width, 1, maskData, 0, 1);
        // apply the mask
        for (int x = 0; x < width; x++) {
            int color = imgData[x] & 0x00FFFFFF; // mask away any alpha present
            int maskColor = (maskData[x] & 0x00FF0000) << 8; // shift red into alpha bits
            color |= maskColor;
            imgData[x] = color;
        }
        // replace the data
        image.setRGB(0, y, width, 1, imgData, 0, 1);
    }
    
        4
  •  1
  •   Thiago Medeiros dos Santos    8 年前

    对于在原始图像中使用alpha的用户。

    我用Koltin写了这段代码,这里的关键点是,如果你的原始图像上有alpha,你需要乘以这些通道。

    科尔廷版本:

        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)
        }
    

        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);
        }
    
        5
  •  0
  •   Zarkonnen    17 年前

    事实上,我已经弄明白了。这可能不是个好主意 快速的 这样做的方式,但它的工作:

    for (int y = 0; y < image.getHeight(); y++) {
        for (int x = 0; x < image.getWidth(); x++) {
            Color c = new Color(image.getRGB(x, y));
            Color maskC = new Color(mask.getRGB(x, y));
            Color maskedColor = new Color(c.getRed(), c.getGreen(), c.getBlue(),
                maskC.getRed());
            resultImg.setRGB(x, y, maskedColor.getRGB());
        }
    }
    
    推荐文章