【问题标题】:Reduce number of colors and get color of a single pixel减少颜色数量并获得单个像素的颜色
【发布时间】:2012-10-08 03:22:48
【问题描述】:

使用 JavaFX 2.2 我需要执行以下操作:

  1. 将给定图像的颜色(例如使用 JavaFX image 类加载)减少到 8 或 16 种颜色,或者可能是 256 种颜色
  2. 访问图像对象中单个像素的颜色 - 好的,看起来 Image.getPixelReader() 应该可以完成这项工作,所以应该只保留第一个问题

谁能给我一些提示或代码示例?谢谢:-)

【问题讨论】:

    标签: image colors javafx-2


    【解决方案1】:
    1. 使用image.getPixelReader() 获取PixelReader 以访问图像中的各个像素。
    2. 创建WritableImage
    3. 获取 WritableImage 的PixelWriter
    4. 遍历从像素读取器读取的像素,通过缩小算法对其调色板运行每个像素,并将缩小后的像素写入像素写入器。

    完成此操作后,您可以在 ImageView 中显示降采样的 WritableImage,或将其转换为 awt imagesave it 为 png、jpg 等格式。

    这里是一些示例代码:

    import javafx.application.Application;
    import javafx.event.*;
    import javafx.geometry.Pos;
    import javafx.scene.Scene;
    import javafx.scene.control.*;
    import javafx.scene.image.*;
    import javafx.scene.layout.VBox;
    import javafx.stage.Stage;
    
    // displays a button with a 64 color image palette and a full color palette when pressed.
    public class ButtonShadeTest extends Application {
      @Override public void start(final Stage stage) throws Exception {
        final Label response = new Label("");
        final Image originalImage = new Image("http://icons.iconarchive.com/icons/eponas-deeway/colobrush/128/heart-2-icon.png");
        final Image resampledImage = resample(originalImage);
        final ImageView imageView = new ImageView(resampledImage);
        final Button button = new Button("I love you", imageView);
        button.setStyle("-fx-base: coral;");
        button.setContentDisplay(ContentDisplay.TOP);
        button.setOnAction(new EventHandler<ActionEvent>() {
          @Override public void handle(ActionEvent event) {
            if ("".equals(response.getText())) {
              response.setText("I love you too!");
              imageView.setImage(originalImage);
            } else {
              response.setText("");
              imageView.setImage(resampledImage);
            } 
          }
        });
    
        final VBox layout = new VBox(10);
        layout.setAlignment(Pos.CENTER);
        layout.getChildren().addAll(button, response);
        layout.setStyle("-fx-background-color: cornsilk; -fx-padding: 10; -fx-font-size: 20;");
        stage.setTitle("Heart");
        stage.getIcons().add(originalImage);
        stage.setScene(new Scene(layout));
        stage.show();
      }
      public static void main(String[] args) { launch(args); }
    
      // downsamples an image to a 64 color palette by only 
      // using the 2 most significant bits of color to represent
      // each of the image's pixels.
      private Image resample(Image inputImage) {
        int W = (int) inputImage.getWidth();
        int H = (int) inputImage.getHeight();
        WritableImage outputImage = new WritableImage(W, H);
        PixelReader reader = inputImage.getPixelReader();
        PixelWriter writer = outputImage.getPixelWriter();
        for (int y = 0; y < H; y++) {
          for (int x = 0; x < W; x++) {
            int argb = reader.getArgb(x, y);
            int a = (argb >> 24) & 0xFF;
            int r = (argb >> 16) & 0xFF;
            int g = (argb >>  8) & 0xFF;
            int b =  argb        & 0xFF;
    
            r = r & 0xC0;
            g = g & 0xC0;
            b = b & 0xC0;
    
            argb = (a << 24) | (r << 16) | (g << 8) | b;
            writer.setArgb(x, y, argb);
          }
        }
    
        return outputImage;
      }
    }
    // icon license: (creative commons with attribution) http://creativecommons.org/licenses/by-nc-nd/3.0/
    // icon artist attribution page: (eponas-deeway) http://eponas-deeway.deviantart.com/gallery/#/d1s7uih
    

    当心碎时,它会以缩小的调色板显示,当心完整时,它会以完整的调色板显示。

    【讨论】:

    • 谢谢,但实际上缩小算法是问题所在,我不知道该怎么做;-)
    • 添加了一个包含缩减算法的示例。
    • 太棒了,感谢您提供示例代码!还不能测试它,但会在接下来的几天里测试它,现在只想说声谢谢!
    猜你喜欢
    • 2016-04-06
    • 2013-07-06
    • 1970-01-01
    • 1970-01-01
    • 2011-08-19
    • 1970-01-01
    • 2017-05-01
    相关资源
    最近更新 更多