Image processing Javafx对图像像素应用过滤器
我正在编写一个照片管理应用程序github.com/lanthale/photoslide,因此我想实现basich图像增强效果。我的基本过滤器(转换为灰度)正在工作,但如果我移动滑块,在进行更新之前总是需要1秒或2秒。 如何实现即时更新图像的版本 以下是过滤器的代码:Image processing Javafx对图像像素应用过滤器,image-processing,javafx,Image Processing,Javafx,我正在编写一个照片管理应用程序github.com/lanthale/photoslide,因此我想实现basich图像增强效果。我的基本过滤器(转换为灰度)正在工作,但如果我移动滑块,在进行更新之前总是需要1秒或2秒。 如何实现即时更新图像的版本 以下是过滤器的代码: public class SampleFilter { private final Image image; public SampleFilter(Image img) { this.image = img; }
public class SampleFilter {
private final Image image;
public SampleFilter(Image img) {
this.image = img;
}
public Image filter(double redLimit, double greenLimit, double blueLimit) {
if (redLimit == 0) {
redLimit = 0.2162;
greenLimit = 0.7152;
blueLimit = 0.0722;
}
PixelReader pixelReader = image.getPixelReader();
int height = (int) image.getHeight();
int width = (int) image.getWidth();
WritableImage filteredImage = new WritableImage(pixelReader, width, height);
PixelWriter pixelWriter = filteredImage.getPixelWriter();
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) (redLimit * red + greenLimit * green + blueLimit * blue);
int gray = (alpha << 24) + (grayLevel << 16) + (grayLevel << 8) + grayLevel;
pixelWriter.setArgb(x, y, gray);
}
}
return filteredImage;
}
apertureSlider.valueProperty().addListener((o) -> {
executorParallel.submit(() -> {
if (shownImage==null){
lightController.getImageView().setCache(true);
shownImage=lightController.getImageView().getImage();
}
SampleFilter sf=new SampleFilter(shownImage);
double val=apertureSlider.getValue();
Image filteredImage = sf.filter(val, val+0.5, val-0.20);
Platform.runLater(() -> {
lightController.getImageView().setImage(filteredImage);
});
});
});
感谢您提供有关操作像素阵列而不是argb值的提示。我现在有一个版本,几乎可以正常工作。几乎我的意思是,现在可以移动滑块,并且在移动滑块的过程中图像会发生变化。左边有点滞后,但我认为也可以通过一些后台任务或其他优化来消除这一点 以下是更快的版本:
public class SampleFilter {
private final Image image;
private WritableImage filteredImage;
private int[] buffer;
public SampleFilter(Image img) {
this.image = img;
}
public Image filter(double redLimit, double greenLimit, double blueLimit) {
if (redLimit == 0) {
redLimit = 0.2162;
greenLimit = 0.7152;
blueLimit = 0.0722;
}
PixelReader pixelReader = image.getPixelReader();
int height = (int) image.getHeight();
int width = (int) image.getWidth();
if (buffer == null) {
buffer = new int[width * height * 4];
pixelReader.getPixels(0, 0, width, height, PixelFormat.getIntArgbInstance(), buffer, 0, width * 4);
}
filteredImage = new WritableImage(pixelReader, width, height);
PixelWriter pixelWriter = filteredImage.getPixelWriter();
int[] targetBuffer = new int[width * height * 4];
for (int i = 0; i < buffer.length; i++) {
int pixel = buffer[i];
int alpha = ((pixel >> 24) & 0xff);
int red = ((pixel >> 16) & 0xff);
int green = ((pixel >> 8) & 0xff);
int blue = (pixel & 0xff);
int grayLevel = (int) (redLimit * red + greenLimit * green + blueLimit * blue);
int gray = (alpha << 24) + (grayLevel << 16) + (grayLevel << 8) + grayLevel;
targetBuffer[i]=gray;
}
pixelWriter.setPixels(0, 0, width, height, PixelFormat.getIntArgbInstance(), targetBuffer, 0, width*4);
return filteredImage;
}
公共类采样过滤器{
私有最终图像;
私有可写映像筛选器图像;
私有int[]缓冲区;
公共样本过滤器(图像img){
this.image=img;
}
公共图像过滤器(双红限、双绿限、双蓝限){
如果(redLimit==0){
红限=0.2162;
绿限=0.7152;
蓝限=0.0722;
}
PixelReader PixelReader=image.getPixelReader();
int height=(int)image.getHeight();
int width=(int)image.getWidth();
if(buffer==null){
缓冲区=新整数[宽度*高度*4];
pixelReader.getPixels(0,0,宽度,高度,PixelFormat.getIntargBinInstance(),缓冲区,0,宽度*4);
}
filteredImage=新的可写图像(像素阅读器、宽度、高度);
PixelWriter PixelWriter=filteredImage.getPixelWriter();
int[]targetBuffer=新int[宽度*高度*4];
for(int i=0;i>24)和0xff);
int红色=((像素>>16)和0xff);
int绿色=((像素>>8)和0xff);
蓝色整数=(像素和0xff);
int灰度=(int)(红色极限*红色+绿色极限*绿色+蓝色极限*蓝色);
int gray=(alpha a)配置文件以查找瓶颈b)尽一切努力修复瓶颈c)如果瓶颈不可修复,则使其看起来更快(我怀疑-但这是一个没有配置文件的胡乱猜测!-部分问题可能是您太频繁地触发新的筛选过程,请检查是否存在更改)另请注意:您不得从fx应用程序线程访问活动场景图(或其任何属性)中的节点(情况可能是这样,取决于lightController的imageView是否处于活动状态)我怀疑是pixelReader.getArb和pixelWriter.setArgb调用减慢了速度。最好将所有内容读入数组,处理数组(可能在适当的位置,可能制作新副本,取决于算法的需要)然后通过将整个目标阵列传递给pixelWriter,一次设置所有像素。谢谢。我现在设法使用阵列的,这是加速的方法。