javafx argb到灰度转换

时间:2016-03-30 16:39:45

标签: javafx grayscale argb

我知道有类似的问题,但这些问题没有回答我的问题。正如标题所示,我使用的是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;
}

任何人都可以告诉我这是什么问题。

3 个答案:

答案 0 :(得分:4)

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

grayscale

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

答案 1 :(得分:1)

我通过执行以下操作让您的代码正常工作,但我还没有完全弄清楚为什么会出现这种情况。它与Image中存储所需的int值有关。您需要反转灰度值并存储-gray整数。也许是Little / Big Endian问题。使用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.
        }
    }

答案 2 :(得分:0)

如果还考虑了 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;
}
相关问题