【问题标题】:javafx argb to grayscale conversionjavafx argb到灰度转换
【发布时间】:2016-03-30 16:39:44
【问题描述】:

我知道有类似的问题,但这些问题没有回答我的问题。如标题所示,我使用的是 JavaFX Image 类,而不是 bufferedImage。

我使用了this其他问题的答案,但结果图像为空。

这是我的代码:

public static Image toGrayScale(Image sourceImage) {
    PixelReader pixelReader = sourceImage.getPixelReader();

    int width = (int) sourceImage.getWidth();
    int height = (int) sourceImage.getHeight();

    WritableImage grayImage = new WritableImage(width, height);

    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++) {
            int pixel = pixelReader.getArgb(x, y);

            int red = ((pixel >> 16) & 0xff);
            int green = ((pixel >> 8) & 0xff);
            int blue = (pixel & 0xff);

            int grayLevel = (int) (0.2162 * red + 0.7152 * green + 0.0722 * blue) / 3;
            int gray = (grayLevel << 16) + (grayLevel << 8) + grayLevel;

            grayImage.getPixelWriter().setArgb(x, y, gray);

    }
    return grayImage;
}

谁能告诉我问题出在哪里。

【问题讨论】:

  • 你缺少一个括号来关闭你的内部 for 循环。
  • @jewelsea,谢谢,但这不是我想要的。
  • @ManoDestra,那是我的错误。在我的原始源代码中,所有的括号都是关闭的。
  • 您确定需要在int grayLevel = (int) (0.2162 * red + 0.7152 * green + 0.0722 * blue) / 3; 中除以3?在我看来,如果red = green = blue = 0xff0xff / 3,你会得到一些东西

标签: javafx grayscale argb


【解决方案1】:

更新,这个答案仍然有效,它给出了一个黑白单色图像,可以很好地近似灰度图像,但是它与应用于的灰度函数不完全相同图片。要查看差异,请查看此问题中的示例图片:

ColorAdjust 用于调整色相、饱和度、亮度 (HSB) 值,而不是红、绿蓝 (RGB) 值。典型的grayscale algorithm 将 RGB 值乘以特定的常数来生成灰度图像。

因此,如果您需要或想要真正的灰度图像,请执行其他答案中概述的像素操作,而不是此答案中的 ColorAdjust 效果建议。


要从图像中获取灰度,我只需应用 desaturation effect

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.effect.ColorAdjust;
import javafx.scene.image.*;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

public class Desaturation extends Application {
    @Override
    public void start(Stage stage) throws Exception {
        Image image = new Image(
                "http://www.iamqurat.com/wp-content/uploads/2016/02/National_Flower_Rose_flickr_20140901.jpg",
                200,
                0,
                true,
                true
        );

        ImageView original = new ImageView(image);

        ImageView desaturated = new ImageView(image);
        ColorAdjust desaturate = new ColorAdjust();
        desaturate.setSaturation(-1);
        desaturated.setEffect(desaturate);

        Scene scene = new Scene(new HBox(original, desaturated));
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

【讨论】:

    【解决方案2】:

    我通过执行以下操作使您的代码正常工作,但我还没有完全弄清楚为什么会出现这种情况。这与 Image 中存储所需的 int 的值有关。您需要反转灰度值并存储 -gray 整数。也许是小/大端问题。使用ColorAdjust 可能更安全。

        // Put this outside the loops
        // so we have easier access to the writer.
        PixelWriter pixelWriter = grayImage.getPixelWriter(); 
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                int pixel = pixelReader.getArgb(x, y);
    
                int red = ((pixel >> 16) & 0xff);
                int green = ((pixel >> 8) & 0xff);
                int blue = (pixel & 0xff);
    
                int grayLevel = (int) (0.2162 * (double)red + 0.7152 * (double)green + 0.0722 * (double)blue) / 3;
                grayLevel = 255 - grayLevel; // Inverted the grayLevel value here.
                int gray = (grayLevel << 16) + (grayLevel << 8) + grayLevel;
    
                pixelWriter.setArgb(x, y, -gray); // AMENDED TO -gray here.
            }
        }
    

    【讨论】:

      【解决方案3】:

      如果也考虑到alpha就可以了,而且加权和不除以3:

      public static Image toGrayScale(Image sourceImage) {
          PixelReader pixelReader = sourceImage.getPixelReader();
      
          int width = (int) sourceImage.getWidth();
          int height = (int) sourceImage.getHeight();
      
          WritableImage grayImage = new WritableImage(width, height);
      
          for (int y = 0; y < height; y++) {
              for (int x = 0; x < width; x++) {
                  int pixel = pixelReader.getArgb(x, y);
      
                  int alpha = ((pixel >> 24) & 0xff);
                  int red = ((pixel >> 16) & 0xff);
                  int green = ((pixel >> 8) & 0xff);
                  int blue = (pixel & 0xff);
      
                  int grayLevel = (int) (0.2162 * red + 0.7152 * green + 0.0722 * blue);
                  int gray = (alpha << 24) + (grayLevel << 16) + (grayLevel << 8) + grayLevel;
      
                  grayImage.getPixelWriter().setArgb(x, y, gray);
              }           
          }
          return grayImage;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-24
        • 1970-01-01
        • 2018-02-17
        • 1970-01-01
        • 1970-01-01
        • 2011-09-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多