本帖最后由 soulmachine 于 2010-02-06 17:53:07 编辑

解决方案 »

  1.   

    我用png和图片试过了, 没有任何问题.
    估计是你的图片格式, 不防用png试试.
    下面的输出结果
    Biao: ~/Desktop $ ls
    1.png                               BiImage.java                        如何将图片黑白化.webarchive
    Biao: ~/Desktop $ javac BiImage.java 
    Biao: ~/Desktop $ java BiImage 1.png 2.png
    230652
    0
    true
    Biao: ~/Desktop $ javac BiImage.java 
    Biao: ~/Desktop $ java BiImage 1.png 3.png
    230652
    0
    true
    Biao: ~/Desktop $ java BiImage 4.png 5.png
    366444
    0
    true
    Biao: ~/Desktop $ 
      

  2.   

    alpha肯定是指不透明度 对jpg之类的图片应该没有影响 你所指的小问题是什么?
      

  3.   

    alpha对于黑白化应该没有影响。
      

  4.   

    图片保存为PNG BMP 格式的好用,结果为TRUE;
    图片保存为JPG JPEG格式的依然可以黑白化,但结果为FALSE;
      

  5.   

    恩,非常感谢,我再认真测试了一下,对于PNG,GIF,BMP,是没有问题的,检测通过
    1. JPG检测通不过,我觉得还是alpha通道没有处理好。所以,小问题就是,为什么JPG黑白化失败?
    2. alpha没有处理的原因,是因为我不太明白 TYPE_INT_ARGB 和 TYPE_INT_RGB 的区别。我的意思是,java在保存图片时,会不会修改某些像素的值,导致检测通不过?
      

  6.   

    jpg是有损压缩格式 
    存储的时候本身不是按照rgb的方式存储的 读取的时候需要解压缩 转换为rgb的颜色信息 而这个过程是有损的 会产生非黑白的颜色信息也就不足为奇了 
      

  7.   

    也就是说 A像素的颜色信息存为jpg格式再读取出来后和原来A像素的信息有可能是不相等的 
      

  8.   

    TYPE_INT_ARGB 代表图像8位RGBA像素的彩色包装成整数部分。
    TYPE_INT_RGB 代表图像8位RGB像素的彩色包装成整数部分。RGBA是对原始的RGB的扩展,它加入了第四个参数:alpha通道。
      

  9.   


    用 TYPE_INT_ARGB 处理alpha通道
      

  10.   

    我个人认为,LZ说的不太对,我觉得alpha通道与你最好反回FALSE没有关系。
    再说经测试黑白化是成功的,只是读到判断时不好用。
      

  11.   

    万分感谢各位。现在疑问解决了。不过我有个新的疑问。现在这个黑白化思路很简单,就是 r*r +g*g +b*b < 3*128*128,则为黑色,大于则是白色。当一张白色背景,有一个淡黄颜色的字,用这方法一黑白化,就全部是白色了。我把这张图片用photoshop,光影魔术手之类的软件黑白话,这些软件能正常转化,字变成了黑色,没有消失。请问下大家,这是怎么做到的?于是我继续google,发现把图片黑白化一般是先转化为灰度图,再转化为黑白图(gray大于128,为白色,小于,为黑色,很简单),公式是 Gray = 0.212671 * R + 0.715160 * G + 0.072169 * B 。我按这个写了一个灰度化函数,不过转化出来的图很奇怪,代码如下:
    /**
         * 将彩色图转化为灰度图
         * 
         * @param imgFile 图片文件路径
         * @return 一个图片对象
         */
        public BufferedImage gray(String imgFile) {
            int newPixels[] = new int[width * height];
            for(int i = 0; i < width * height; i++) {
                int r = (pixels[i] >> 16) & 0xff;
                int g = (pixels[i] >> 8) & 0xff;
                int b = (pixels[i]) & 0xff;
                
                // 方法1,图像很奇怪
                int gray = (int)(0.229 * r + 0.587 * g + 0.114 * b);
                newPixels[i] = gray << 16 + gray << 8 + gray;
                //方法2,图像偏蓝,不是灰度图
                //newPixels[i] = gray;
            }
            
            // 基于 newPixels 构造一个 BufferedImage
            BufferedImage bi = new BufferedImage(width, height,
                    BufferedImage.TYPE_INT_RGB);
            bi.setRGB(0, 0, width, height, newPixels, 0, width);
            newPixels = null;
            
            try {
                // 写入磁盘
                BiImage.writeImageToFile(imgFile, bi);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
            return bi;
        }参考资料:http://topic.csdn.net/t/20040705/16/3147285.html
      

  12.   

    我也搞了很久 甚至用笔花了半天 最后发现原来是运算符优先级问题汗。。
    这句应该加括号 newPixels[i]= (gray<<16)+ (gray<<8)+ gray;
    这样出来的灰度图就很完美了
      

  13.   

    knightzhuwei,我崇拜你,问题果然在这里。难道Java中运算符优先级和C语言有很大不同吗,太诡异了。
    newPixels[i] = gray << 16 + gray << 8 + gray;newPixels[i]= (gray < <16)+ (gray < <8)+ gray; 这两者有区别吗,按说括号是不必要的吧。不过,问题解决了,感谢各位,给分结贴!各位真的好热心,再次感谢!