【问题标题】:The below java code for putting transparency to specific color works in my laptop but not on other laptops with better graphics card, WHY? [duplicate]以下用于将透明度设置为特定颜色的 Java 代码在我的笔记本电脑上工作,但在其他显卡更好的笔记本电脑上却不行,为什么? [复制]
【发布时间】:2012-04-01 22:29:08
【问题描述】:

可能重复:
I am making some parts of java image transparent by some code, it works fine on the laptop I made, but not on others, Why?

图像测试:原始图像,
Image testt : 应用透明度后的图像

在我的笔记本电脑中,我想要透明的颜色变成透明的,test 和 testt 都被渲染了,但是在没有绘制 testt 图像的地方,绘制了测试但没有绘制 testt。

绘制简单透明图片的完整代码:

import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.awt.image.ImageProducer;
import java.awt.image.RGBImageFilter;
import java.io.Serializable;


public class test extends Applet implements Runnable
{
    public static Image makeColorTransparent(Image im, final Color color) 
      {
        ImageFilter filter = new RGBImageFilter() 
        {

              public int markerRGB = color.getRGB() | 0xFF000000;               //color to make transparent

              public final int filterRGB(int x, int y, int rgb) 
              {
                if ( ( rgb | 0xFF000000 ) == markerRGB ) 
                {
                  // Mark the alpha bits as zero - transparent
                  return 0x00FFFFFF & rgb;
                }

                else 
                {
                  // nothing to do
                  return rgb;
                }
             }
        }; 

            ImageProducer ip = new FilteredImageSource(im.getSource(), filter);
            return Toolkit.getDefaultToolkit().createImage(ip);

      }


    Image test;
    public void init()
    {

        setSize(600,600);

    }

    public void update (Graphics g)                                             //overriding the update for double buffering
    {       
        // initialize buffer
        Image dbImage = createImage (this.getSize().width, this.getSize().height);
        Graphics dbg = dbImage.getGraphics ();


        // clear screen in background
        dbg.setColor (getBackground());
        dbg.fillRect (0, 0, this.getSize().width, this.getSize().height);


        // draw elements in background
        dbg.setColor (getForeground());
        paint (dbg);

        // draw image on the screen
        g.drawImage (dbImage, 0, 0, this);      
    }


    public void paint(Graphics g)
    {
        test = getImage(getCodeBase (), "tt.gif");
        Image testt = makeColorTransparent(test, Color.white);               

        g.drawImage (testt,0,0, this);
    }


    @Override
    public void run() {
        // TODO Auto-generated method stub
        repaint();

    }

}

【问题讨论】:

  • 会不会与 32/64 位环境有关?我不确定 64 位 java 是否使用 64 位颜色,但如果是,那可能是你的问题,因为位掩码搞砸了。
  • 您确定文件“tt.gif”确实存在于您启动应用程序的其他计算机上吗?并且在应用程序找到它所需的确切路径上?
  • 是的,tt.gif 位于两台计算机项目文件夹的 bin 文件夹中...
  • 由于您使用与图像输入相同的 GIF 文件,我现在怀疑还有别的东西。也许,您应该提供有关这两个系统的更多信息:它的操作系统、它的 JRE 版本? OS/JRE 中的 32 位还是 64 位?专用 GPU 还是集成 GPU?
  • @Accatyyc 颜色深度不会随 CPU 位数而变化,并且无论 VM 如何,Java 的数据类型大小都相同。 (也就是说,int 在 32 位和 64 位 JVM 上都是 32 位宽,并且它们都使用相同的运行时,其中像素为 ints。)

标签: java transparency


【解决方案1】:

在How to make a color transparent in a BufferedImage and save as PNG中使用PhiLho的解决方案

  private Image TransformColorToTransparency(BufferedImage image, Color c1, Color c2)
  {
    // Primitive test, just an example
    final int r1 = c1.getRed();
    final int g1 = c1.getGreen();
    final int b1 = c1.getBlue();
    final int r2 = c2.getRed();
    final int g2 = c2.getGreen();
    final int b2 = c2.getBlue();
    ImageFilter filter = new RGBImageFilter()
    {
      public final int filterRGB(int x, int y, int rgb)
      {
        int r = (rgb & 0xFF0000) >> 16;
        int g = (rgb & 0xFF00) >> 8;
        int b = rgb & 0xFF;
        if (r >= r1 && r <= r2 &&
            g >= g1 && g <= g2 &&
            b >= b1 && b <= b2)
        {
          // Set fully transparent but keep color
          return rgb & 0xFFFFFF;
        }
        return rgb;
      }
    };

    ImageProducer ip = new FilteredImageSource(image.getSource(), filter);
      return Toolkit.getDefaultToolkit().createImage(ip);
  }

或者,http://marxsoftware.blogspot.com/2011/04/making-white-image-backgrounds.html

   public static Image makeColorTransparent(final BufferedImage im, final Color color)  
   {  
      final ImageFilter filter = new RGBImageFilter()  
      {  
         // the color we are looking for (white)... Alpha bits are set to opaque  
         public int markerRGB = color.getRGB() | 0xFFFFFFFF;  

         public final int filterRGB(final int x, final int y, final int rgb)  
         {  
            if ((rgb | 0xFF000000) == markerRGB)  
            {  
               // Mark the alpha bits as zero - transparent  
               return 0x00FFFFFF & rgb;  
            }  
            else  
            {  
               // nothing to do  
               return rgb;  
            }  
         }  
      };  

      final ImageProducer ip = new FilteredImageSource(im.getSource(), filter);  
      return Toolkit.getDefaultToolkit().createImage(ip);  
   }  
}

很明显,你的问题和第二种解决方案的区别就在这里:

public int markerRGB = color.getRGB() | 0xFF000000;   

您正在寻找将黑色设置为透明色而不是白色的地方。

MIT 的解决方案http://web.mit.edu/javalib/www/examples/if/start.html

class TransparentFilter extends RGBImageFilter {

    final static int aShift=24;
    final static int rShift=16;
    final static int gShift=8;
    final static int bShift=0;
    final static int aMask=0xff<<aShift;
    final static int rMask=0xff<<rShift;
    final static int gMask=0xff<<gShift;
    final static int bMask=0xff<<bShift;
    final static int rgbMask=rMask|gMask|bMask;

    // this fudge value is used in place of the harder (but proper) task of
    // performing statistical analysis of the saturation values (and
    // possibly distances) of highly-saturated pixels contained in the image
    float saturationFudge;

    TransparentFilter(float saturationFudge) {
        this.saturationFudge=saturationFudge;
        canFilterIndexColorModel=true;
    }

    public int filterRGB(int x, int y, int argb) {
        // separate the three colour channels (ignore incoming alpha)
        int r=(argb&rMask) >>> TransparentFilter.rShift;
        int g=(argb&gMask) >>> TransparentFilter.gShift;
        int b=(argb&bMask) >>> TransparentFilter.bShift;
        // convert to hsb so that we can use saturation to
        // establish the alpha (transparency) value of the pixel
        float[] hsb=Color.RGBtoHSB(r,g,b,null);
        float fa=255f*hsb[1]/this.saturationFudge;
        int a=Math.max(0,Math.min(255,Math.round(fa)))<<TransparentFilter.aShift;
        return a|(argb&TransparentFilter.rgbMask);
    }

}

不过,如果所有解决方案都无法在测试系统上正常运行,我们可能会怀疑其他可能的罪魁祸首,根据您的原始帖子,我们没有足够的信息:

  1. 操作系统版本 32/64 位?
  2. JRE/JDK 版本 32/64 位?
  3. GPU:硬件和驱动程序?
  4. 显示:256 位/16 位/24 位?

此外,由于没有提供屏幕截图,我们不知道您在这些系统之间观察到了什么。

最糟糕的是,您必须开始使用已设置透明蒙版的图像来解决您的问题,而不是依赖于对其透明度位进行编码(除非您尝试创建需要透明度过滤器的基于 Java 的照片编辑应用程序)。

可能未解决的相关问题??:

  1. Java Swing transparency drawing issues

【讨论】:

    猜你喜欢
    • 2012-04-14
    • 2020-09-27
    • 1970-01-01
    • 2013-08-23
    • 2018-06-20
    • 2011-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多