【问题标题】:Verify Android Bitmap is GrayScale验证 Android 位图是灰度
【发布时间】:2012-06-13 00:21:23
【问题描述】:

我有一个疑问。当我从 Android 中的 Bitmap 获取像素时。我在里面加载了一张图片,这张图片是灰度图。如果我创建 getPixels() 并检查值,我可以看到 R != G != B 的值。

如果三张幻灯片(R、G 和 B)的值相同,我想我可以检查它是否是灰度,但我不可能。 有办法验证吗?

非常感谢!

【问题讨论】:

    标签: android image-processing bitmap grayscale


    【解决方案1】:

    首先要说有几种方法可以做到这一点。

    我会说使用(类似)获取图像的大小

    int myHeight = myImage.getHeight();
    int myWidth  = myImage.getWidth();
    

    我想说,在这种情况下,您可能还想验证位图的配置,因为它可能是 3 种不同格式之一

    ALPHA_8, ARGB_8888, or RGB_565
    

    您使用

    获取配置
    myImage.getConfig()
    

    例行公事。稍后我们将讨论如何使用它。

    既然您知道图像的大小,您应该运行如下双循环结构:

    boolean isGrayscaleImage = true;  // assume it is grayscale until proven otherwise
    
    for(int i = 0; i < myWidth; i++){
        for(int j = 0; j < myHeight; j++){
            int currPixel = myImage.getPixel(i, j);
    
            if( false == isGrayScalePixel(currPixel) ){
                isGrayscaleImage = false;
                break;
            }
        }
    }
    

    返回如何测试像素是否为灰度: 如果图像存储为 ALPHA_8,它实际上不是灰度图像,但从技术上讲,它可以通过将图像转换为 ARGB_8888 图像并将 Alpha 值设置为 0xFF 以及 R、G 和 B 分量中的每一个来转换为灰度图像转换为原始 8 位基于 ALPHA_8 的图像中提供的 alpha 值。

    如果图像是 RGB_565 格式,这有点棘手,因为您必须自己使用 shift 和 MASKING 运算符将 R、G 和 B 值拆分为它们自己的字节。完成此操作后,它本质上就像处理 ARGB_8888 图像(在下面讨论)。

    对于 ARGB_8888 图像: Alpha 通道应始终为 0xFF。

    正如您在问题中所述,如果 R == G == B,则将像素视为灰度 SO(示例代码可能如下所示)

    boolean isGrayScalePixel(int pixel){
        int alpha = (pixel && 0xFF000000) >> 24;
        int red   = (pixel && 0x00FF0000) >> 16;
        int green = (pixel && 0x0000FF00) >> 8;
        int blue  = (pixel && 0x000000FF);
    
        if( 0 == alpha && red == green && green == blue ) return true;
        else return false;
    
    }
    

    可以进行一些优化,但我正在尝试为您记录主要算法。

    希望这可以帮助你:-)

    【讨论】:

    • 这就是我所做的,但是灰度图像中的像素得到了不同的值,我认为,和你一样,它们应该得到相同的值。那是我的问题。
    • 嗯............这就是你验证的方式,这就是你的问题。你有没有实际的图像,你有没有在成像应用程序中打开它并放大看是否确实有非灰度的颜色???
    • 我在加载图像后立即应用验证作为图像的预处理步骤,无需缩放或其他不同操作。如果这个图像是用 Matlab 打开的,我发现它是一个只有一层的图像,它是一个灰度图像(不是索引彩色图像),像素级别从 0 到 255。
    • 您是否检查过它是 ARGB_8888 还是 ARGB_565?当您说 R != G != B 时,值相差多远?
    • 发现问题。那就是所有图像都加载为 ARGB_565 并且 R 或 B 的值比例与 G 不同。解决方案是强制 decodeFile() 函数将 options.preferredConfig 参数设置为 ARGB_8888。然后每个人都可以在相同的尺度下得到正确的值。
    【解决方案2】:

    注意在屏蔽时使用 &&(布尔与)应为单个 &(按位与),如下所示:

    int alpha = (pixel & 0xFF000000) >> 24;
    int red   = (pixel & 0x00FF0000) >> 16;
    int green = (pixel & 0x0000FF00) >> 8;
    int blue  = (pixel & 0x000000FF);
    

    【讨论】:

      【解决方案3】:

      如果您只需检查 R、G 和 B 值是否相同,则只需使用 Colors.red()Colors.green()Colors.blue() 即可。

      这是实际代码的一小部分。

      for(int x=0;x< bmp.getWidth();x++) {
          for(int y=0;y< bmp.getHeight();y++) {    
      
              int pixel=bmp.getPixel(x,y);
              int alpha=Color.alpha(pixel);            
              int gray_color=Color.red(pixel);         
              int gray_color1=Color.green(pixel);
      
              //int gray_color=pixel&0x000000ff;
              //int gray_color1=(pixel&0x0000ff00)>>8;
              //int gray_color2=(pixel&0x00ff0000)>>16;
              //int gray_color3=Math.abs((pixel&0xff000000))>>24;
      
              int pixels= (int)Math.pow(gray_color,gamma);
              k.add(""+alpha+" "+gray_color+" "+gray_color1);
              bmp.setPixel(x,y,Color.argb(alpha,pixels,pixels,pixels));
          }
      }
      

      你可以看到我已经评论了移位和遮罩部分。

      【讨论】:

        猜你喜欢
        • 2023-03-31
        • 1970-01-01
        • 2012-03-30
        • 1970-01-01
        • 2011-03-23
        • 2023-04-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多