JavaFX PixelWriter低性能
我创建了一个简单的JavaFX图像编辑器。ImageView有两个实例(打开用于原始图像,一个用于已编辑图像)。 方法将可写图像转换为灰度。 问题是,转换所需的时间大约是Swing执行相同任务所需时间的两倍。知道为什么吗JavaFX PixelWriter低性能,java,swing,javafx,imageview,Java,Swing,Javafx,Imageview,我创建了一个简单的JavaFX图像编辑器。ImageView有两个实例(打开用于原始图像,一个用于已编辑图像)。 方法将可写图像转换为灰度。 问题是,转换所需的时间大约是Swing执行相同任务所需时间的两倍。知道为什么吗 @FXML void loadImage(ActionEvent event) { FileChooser fileChooser = new FileChooser(); File file = fileChooser.showOpenDialog(Main.
@FXML
void loadImage(ActionEvent event) {
FileChooser fileChooser = new FileChooser();
File file = fileChooser.showOpenDialog(Main.primaryStage);
if (file != null) {
Image image = new Image("file:" + file.getAbsolutePath());
imViewOrig.setImage(image);
PixelReader pr = imViewOrig.getImage().getPixelReader();
WritableImage wi = new WritableImage(
pr,
(int)imViewOrig.getImage().getWidth(),
(int)imViewOrig.getImage().getHeight());
imViewEdit.setImage(wi);
}
}
@FXML
void greyscale(ActionEvent event) {
PixelReader pr = imViewOrig.getImage().getPixelReader();
PixelWriter pw = ((WritableImage)imViewEdit.getImage()).getPixelWriter();
long beginTime = System.currentTimeMillis();
for (int x = 0; x < imViewEdit.getImage().getWidth(); x++) {
for (int y = 0; y < imViewEdit.getImage().getHeight(); y++) {
Color c = pr.getColor(x, y);
double avg = (c.getRed() + c.getGreen() + c.getBlue()) / 3.;
Color grey = new Color(avg, avg, avg, c.getOpacity());
pw.setColor(x, y, grey);
}
}
System.out.println(System.currentTimeMillis() - beginTime + "ms");
}
@FXML
无效加载映像(ActionEvent事件){
FileChooser FileChooser=newfilechooser();
File File=fileChooser.showOpenDialog(Main.primaryStage);
如果(文件!=null){
图像=新图像(“文件:”+file.getAbsolutePath());
imViewOrig.setImage(图像);
PixelReader pr=imViewOrig.getImage().getPixelReader();
WritableImage wi=新的WritableImage(
公共关系,
(int)imViewOrig.getImage().getWidth(),
(int)imViewOrig.getImage().getHeight());
imViewEdit.setImage(wi);
}
}
@FXML
无效灰度(ActionEvent事件){
PixelReader pr=imViewOrig.getImage().getPixelReader();
PixelWriter pw=((WritableImage)imViewEdit.getImage()).getPixelWriter();
long beginTime=System.currentTimeMillis();
对于(int x=0;x
回转代码:
public void greyscale() {
long beginTime = System.currentTimeMillis();
for (int x = 0; x < image.getWidth(); x++) {
for (int y = 0; y < image.getHeight(); y++) {
Color c = new Color(image.getRGB(x, y));
int avg = (c.getRed() + c.getGreen() + c.getBlue()) / 3;
Color grey = new Color(avg, avg, avg);
image.setRGB(x, y, grey.getRGB());
}
}
repaint();
System.out.println(System.currentTimeMillis() - beginTime + "ms");
}
public void greyscale(){
long beginTime=System.currentTimeMillis();
对于(int x=0;x
在快速测试中,如果只进行int
计算,而不是操作颜色
对象,它的工作速度会快10倍。JavaFXColor
类是比AWTColor
类更丰富的实现;我想这是以额外的开销为代价的
int width = (int)image.getWidth();
int height = (int)image.getHeight();
int[] pixels = new int[width * height];
WritablePixelFormat<IntBuffer> pixelFormat = PixelFormat.getIntArgbPreInstance();
pr.getPixels(0, 0, width, height, pixelFormat, pixels, 0, width);
int[] newPixels = new int[pixels.length];
for (int i = 0 ; i < pixels.length; i++) {
int c = pixels[i];
int a = c & 0xFF000000 ;
int r = (c >> 16) & 0xFF ;
int g = (c >> 8) & 0xFF ;
int b = c & 0xFF ;
int gray = (r+g+b) / 3 ;
newPixels[i] = a | (gray << 16) | (gray << 8) | gray ;
}
pw.setPixels(0, 0, width, height, pixelFormat, newPixels, 0, width);
intwidth=(int)image.getWidth();
int height=(int)image.getHeight();
int[]像素=新int[宽度*高度];
WritablePixelFormat pixelFormat=pixelFormat.getIntArgbPreInstance();
pr.getPixels(0,0,宽度,高度,像素格式,像素,0,宽度);
int[]newPixels=新int[pixels.length];
对于(int i=0;i>16)和0xFF;
int g=(c>>8)&0xFF;
intb=c&0xFF;
int gray=(r+g+b)/3;
newPixels[i]=一个基于|(灰度的样本,当鼠标悬停在图像上时,通过降低饱和度将彩色图像转换为单色
给定适当的硬件(大多数JavaFX运行系统都可以使用该硬件),JavaFX运行时可能会在硬件中执行一些颜色调整的实现,这可能会导致一种比使用图形处理像素更有效的实现
作为替代实现,您可以应用一种效果来降低颜色的饱和度。很好,Swing有类似的功能吗?我认为Swing-around图像的大多数低级原语都在awt类中。与JavaFX最接近的是。免责声明:我对Swing知之甚少。我还忘记了我的大部分Swing/AWT技能,但您可以尝试修改现有代码以避免创建Color
对象。有一个buffereImage.getRGB(…)
用像素数据填充int[]
;您可以用与JavaFX代码相同的方式提取红色、绿色和蓝色组件(没有alpha组件),然后映射到一个新数组中,并调用BufferedImage.setRGB(…)
。
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.scene.*;
import javafx.scene.effect.*;
import javafx.scene.image.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class Shadow extends Application {
@Override
public void start(Stage stage) throws Exception {
Image image = new Image(
"http://icons.iconarchive.com/icons/designbolts/smurfs-movie/512/smurfette-icon.png"
);
ImageView imageView = new ImageView(image);
ColorAdjust monochrome = new ColorAdjust();
monochrome.setSaturation(-1.0);
imageView.effectProperty().bind(
Bindings
.when(imageView.hoverProperty())
.then(monochrome)
.otherwise((ColorAdjust) null)
);
stage.setScene(new Scene(new Group(imageView), Color.AQUA));
stage.show();
}
public static void main(String[] args) {
Application.launch();
}
}