2015-05-06 114 views
0

我在JavaFX中獲得了一個彩色區域,並且想要在其上顯示文本。 文本顏色應該是白色或黑色,具體取決於背景的隱藏亮度 。以下是JavaFX.Color#getBrightness給出的方法。但是這種方法並不令人信服,因爲我需要選擇白色來獲得高達0.9的亮度。JavaFX:獲得percieved顏色的亮度

if (getColor().getBrightness() < 0.9) { 
    setStyle("-fx-text-fill: " + "white" + ";"); 
} else { 
    setStyle("-fx-text-fill: " + "black" + ";"); 
} 

不過,結果看起來窮了許多背景顏色:

enter image description here

enter image description here

回答

2

如果你可以定義CSS背景顏色太(也許用查到的顏色),那麼你可以使用css顏色函數ladder(...)來定義文本填充的背景顏色。喜歡的東西:

.text-pane { /* pane containing the text */ 
    -text-background: red ; 
    -fx-background-color: -text-background ; 
} 
.text-pane .text { 
    -fx-fill: ladder(-text-background, white 0%, white 59%, black 60%, black 100%); 
} 

注意如果要動態地在運行時選擇的背景,你可以使用這種技術,你可以使用內嵌樣式更改在樣式表中定義查找到的顏色值:

Color color = ... ; // some color 
String style = String.format("-text-background: rgba(%d, %d, %d, %f);", 
    (int)(color.getRed()*255), 
    (int)(color.getGreen()*255), 
    (int)(color.getBlue()*255), 
    color.getOpacity()); 
somePane.setStyle(style); 

這是作爲默認使用由Label(和其他控制)相同的技術。在這種情況下查找的顏色是-fx-background。所以,如果你這樣做:

Label foo = new Label("Foo"); 
Label bar = new Label("Bar"); 
foo.setStyle("-fx-background: white;"); // automatically gets dark text 
bar.setStyle("-fx-background: black;"); // automatically get white text 

完整的演示:

import javafx.application.Application; 
import javafx.scene.Node; 
import javafx.scene.Scene; 
import javafx.scene.control.CheckBox; 
import javafx.scene.control.Label; 
import javafx.scene.layout.HBox; 
import javafx.scene.layout.StackPane; 
import javafx.scene.layout.VBox; 
import javafx.scene.text.Text; 
import javafx.stage.Stage; 

public class LookedUpColorDemo extends Application { 

    @Override 
    public void start(Stage primaryStage) { 
     Text text1 = new Text("Foo"); 
     text1.getStyleClass().add("text"); 
     Text text2 = new Text("Bar"); 
     text2.getStyleClass().add("text"); 
     StackPane textPane1 = new StackPane(text1); 
     textPane1.getStyleClass().add("text-pane"); 
     StackPane textPane2 = new StackPane(text2); 
     textPane2.getStyleClass().add("text-pane"); 
     Label label1 = new Label("Foo label"); 
     Label label2 = new Label("Bar label"); 
     VBox root = new VBox(10, 
       new HBox(5, textPane1, createCheckBox(textPane1, "-text-background")), 
       new HBox(5, textPane2, createCheckBox(textPane2, "-text-background")), 
       new HBox(5, label1, createCheckBox(label1, "-fx-background")), 
       new HBox(5, label2, createCheckBox(label2, "-fx-background")) 
     ); 
     Scene scene = new Scene(root, 400, 250); 
     scene.getStylesheets().add("looked-up-color-demo.css"); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    private CheckBox createCheckBox(Node node, String lookedUpColorName) { 
     CheckBox cb = new CheckBox(); 
     cb.selectedProperty().addListener((obs, wasSelected, isNowSelected) -> { 
      if (isNowSelected) { 
       node.setStyle(lookedUpColorName + ": black;"); 
      } else { 
       node.setStyle(lookedUpColorName + ": white;");    
      } 
     }); 
     return cb ; 
    } 

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

隨着css文件查到的,顏色demo.css:

.label { 
    -fx-background: white ; 
    -fx-background-color: -fx-background ; 
} 
.text-pane { 
    -text-background: white ; 
    -fx-background-color: -text-background ; 
} 
.text-pane .text { 
    -fx-fill: ladder(-text-background, white 0%, white 59%, black 60%, black 100%); 
} 
+0

如果這是一個'標籤',順便說一句,這已經內置了... –

+0

感謝您的選擇,但我不能使用CSS顏色,因爲顏色是直到運行時才創建的 – Brian

+0

您仍然可以做到這一點。查看更新。 –

1

你可以給一個嘗試YUV (https://en.wikipedia.org/wiki/YUV)。簡而言之:將RGB中的顏色轉換爲YUV並查看Y分量(這就是所謂的亮度 - 這是亮度 - 事實上,舊的單色電視系統將其用於圖像編碼),因爲這大致對應於顏色的亮度以灰度顯示(注意RGB#00F,藍色,相當黑暗,而RGB#0F0,綠色,如果你看Y分量,則相當輕,你的G和B分量都有相同的值),這就是你正在找。通過比較亮度(亮度),您可以判斷人類認爲是「更亮」還是「更暗」,並據此調整調色板設置。但是,Color#getBrighteness()實際上可能是YUV的Y組件(JavaDoc並未這麼說)。