首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CollorAdjust和SwingX的ImageView?

CollorAdjust和SwingX的ImageView?
EN

Stack Overflow用户
提问于 2015-02-27 00:08:30
回答 2查看 759关注 0票数 0

我有一个问题,如何调整从swingx库加载到jXImageView的图像的对比度、饱和度和色调。

我有ColorAdjust方法。

代码语言:javascript
复制
ColorAdjust colorAdjust = new ColorAdjust();
colorAdjust.setContrast(0.3);
colorAdjust.setHue(-0.03);
colorAdjust.setBrightness(0.2);
colorAdjust.setSaturation(0.2);

当用户点击“增强”按钮时,图像应该会发生一些变化,但是如何做到呢?记住:我正在使用jXImageView。

通过使用以下代码,我已经增加了对比:

代码语言:javascript
复制
    float brightenFactor = 1.5f;
    BufferedImage imagem = (BufferedImage) jXImageView2.getImage();
    RescaleOp op = new RescaleOp(brightenFactor, 0, null);
    imagem = op.filter(imagem, imagem);
    jXImageView2.updateUI();

编辑

我试着:

代码语言:javascript
复制
BufferedImage imagem = (BufferedImage) jXImageView2.getImage();
Image image = SwingFXUtils.toFXImage(imagem, null);//<--ERROR on that line (incompatible types: writable image cannot be converted to Image)
ColorAdjust colorAdjust = new ColorAdjust();
colorAdjust.setContrast(0.3);
colorAdjust.setHue(-0.03);
colorAdjust.setBrightness(0.2);
colorAdjust.setSaturation(0.2);
ImageView imageView = new ImageView(image);//<--ERROR on taht line no suitable constructor for ImageView(java.awt.Image)
imageView.setFitWidth(imagem.getWidth());
imageView.setPreserveRatio(true);
imagem = SwingFXUtils.fromFXImage(imageView.snapshot(null, null), null);
jXImageView2.setImage(imagem);

...but没有成功。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-02-27 02:11:53

样品溶液

  • 左边的图像是原始图像。
  • 右边的图像是调整后的图像(该图像的颜色已经去饱和以使图像单色)。

该解决方案的工作方式是:

  1. 将Swing/AWT BufferedImage转换为JavaFX 图像
  2. 使用JavaFX ColorAdjust效果来修改图像。
  3. 采用颜色调整图像的快照来创建新的JavaFX图像。
  4. 新的JavaFX映像是转换成返回到一个新的Swing/AWT BufferedImage。

由于该解决方案混合了两个不同的工具箱,因此在创建它时应用了以下注意事项:

  1. 注意用于确保给定工具箱调用使用正确类的导入;例如,JavaFX和Swing/AWT都有ColorImage类,因此有必要确保在正确的上下文中使用给定工具包的完全限定类--将Swing映像直接传递给JavaFX API是错误的,反之亦然。
  2. 小心线程规则。JavaFX场景的快照必须在JavaFX应用程序线程上进行。必须在Swing事件分派线程上执行Swing API。使用相应工具包(例如SwingUtilities和JavaFX Platform类)的各种实用程序来确保满足给定工具箱的线程约束。
  3. 必须对JavaFX工具包进行初始化才能使用它。通常,这是在应用程序扩展JavaFX Application类时隐式完成的。但是,Swing应用程序不扩展JavaFX应用程序类。因此,在使用工具箱之前,必须实例化一个JFXPanel来初始化JavaFX工具包,这可能有点违背直觉,而且文档也不多。

Notes

  1. 此解决方案是为满足问题的特殊要求而设计的( Swing应用程序需要进行一些颜色调整)。如果您只希望从JavaFX内部调整图像颜色,而不使用Swing,则更直接的解决方案是首选。
  2. 调用System.exit通常足以关闭JavaFX工具包。示例应用程序调用Platform.exit显式关闭JavaFX工具包,但在这种情况下,可能没有必要显式调用Platform.exit

这意味着解决方案中的ColorAdjuster可以从Swing程序中使用,而无需Swing程序显式导入任何JavaFX类(尽管在内部,ColorAdjuster将导入这些类,系统必须满足运行Swing和JavaFX工具包的正常最低要求)。在可能的情况下,减少将导入混合到每个类的单个工具包是可取的,因为混合JavaFX/Swing应用程序在单个类中混合导入是一个很好的麻烦来源,因为潜在的名称冲突和与线程相关的问题。

ColorAdjuster.java

图像调色实用程序。

代码语言:javascript
复制
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.SnapshotParameters;
import javafx.scene.effect.ColorAdjust;
import javafx.scene.image.ImageView;
import javafx.scene.paint.Color;

import javax.swing.SwingUtilities;
import java.awt.image.BufferedImage;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/** Uses JavaFX to adjust the color of an AWT/Swing BufferedImage */
public class ColorAdjuster {
    // Instantiation of a JFXPanel is necessary otherwise the JavaFX toolkit is not initialized.
    // The JFXPanel doesn't actually need to be used, instantiating it in the constructor is enough to trigger toolkit initialization.
    private final JFXPanel fxPanel;

    public ColorAdjuster() {
        // perhaps this check is not necessary, but I feel a bit more comfortable if it is there.
        if (!SwingUtilities.isEventDispatchThread()) {
            throw new IllegalArgumentException(
                    "A ColorAdjuster must be created on the Swing Event Dispatch thread.  " +
                            "Current thread is " + Thread.currentThread()
            );
        }

        fxPanel = new JFXPanel();
    }

    /** 
     * Color adjustments to the buffered image are performed with parameters in the range -1.0 to 1.0
     * 
     * @return a new BufferedImage which has colors adjusted from the original image.
     **/
    public BufferedImage adjustColor(
            BufferedImage originalImage,
            double hue,
            double saturation,
            double brightness,
            double contrast
    ) throws ExecutionException, InterruptedException {
        // This task will be executed on the JavaFX thread.
        FutureTask<BufferedImage> conversionTask = new FutureTask<>(() -> {
            // create a JavaFX color adjust effect.
            final ColorAdjust monochrome = new ColorAdjust(0, -1, 0, 0);

            // convert the input buffered image to a JavaFX image and load it into a JavaFX ImageView.
            final ImageView imageView = new ImageView(
                    SwingFXUtils.toFXImage(
                            originalImage, null
                    )
            );

            // apply the color adjustment.
            imageView.setEffect(monochrome);

            // snapshot the color adjusted JavaFX image, convert it back to a Swing buffered image and return it.
            SnapshotParameters snapshotParameters = new SnapshotParameters();
            snapshotParameters.setFill(Color.TRANSPARENT);

            return SwingFXUtils.fromFXImage(
                    imageView.snapshot(
                            snapshotParameters,
                            null
                    ),
                    null
            );
        });

        Platform.runLater(conversionTask);

        return conversionTask.get();
    }
}

ColorAdjustingSwingAppUsingJavaFX.java

测试线束:

代码语言:javascript
复制
import javafx.application.Platform;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.ExecutionException;

public class ColorAdjustingSwingAppUsingJavaFX {

    private static void initAndShowGUI() {
        try {
            // This method is invoked on Swing thread
            JFrame frame = new JFrame();

            // read the original image from a URL.
            URL url = new URL(
                    IMAGE_LOC
            );
            BufferedImage originalImage   = ImageIO.read(url);

            // use JavaFX to convert the original image to monochrome.
            ColorAdjuster colorAdjuster = new ColorAdjuster();
            BufferedImage monochromeImage = colorAdjuster.adjustColor(
                    originalImage,
                    0, -1, 0, 0
            );

            // add the original image and the converted image to the Swing frame.
            frame.getContentPane().setLayout(new FlowLayout());
            frame.getContentPane().add(
                    new JLabel(
                            new ImageIcon(originalImage)
                    )
            );
            frame.getContentPane().add(
                    new JLabel(
                            new ImageIcon(monochromeImage)
                    )
            );

            // set a handler to close the application on request.
            frame.addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent e) {
                    // shutdown the JavaFX runtime.
                    Platform.exit();

                    // exit the application.
                    System.exit(0);
                }
            });

            // display the Swing frame.
            frame.pack();
            frame.setLocation(400, 300);
            frame.setVisible(true);
        } catch (IOException | InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(
                ColorAdjustingSwingAppUsingJavaFX::initAndShowGUI
        );
    }


    // icon source: http://www.iconarchive.com/artist/aha-soft.html
    // icon license: Free for non-commercial use, commercial usage: Not allowed
    private static final String IMAGE_LOC =
            "http://icons.iconarchive.com/icons/aha-soft/desktop-buffet/128/Pizza-icon.png";
}
票数 2
EN

Stack Overflow用户

发布于 2015-02-27 00:42:46

如果您需要将BufferedImage转换为javafx.scene.image.Image,您可以使用类似于.

代码语言:javascript
复制
Image image = SwingFXUtils.toFXImage(imagem, null);

然后你可以应用ColorAdjust.

代码语言:javascript
复制
ColorAdjust colorAdjust = new ColorAdjust();
colorAdjust.setContrast(0.1);
colorAdjust.setHue(-0.05);
colorAdjust.setBrightness(0.1);
colorAdjust.setSaturation(0.2);

ImageView imageView = new ImageView(image);
imageView.setFitWidth(image.getWidth());
imageView.setPreserveRatio(true);
imageView.setEffect(colorAdjust);

然后再把它改回来..。

代码语言:javascript
复制
imagem = SwingFXUtils.fromFXImage(imageView.snapshot(null, null), null);

这个想法是从珠宝商/ SaveAdjustedImage.java偷来的。我不知道的是,如果ImageView需要首先在屏幕上实现--不是.

更新的

就像电影里说的那样,你正在穿越两个不同的UI框架,“不要横过溪流!”

JavaFX有一组比Swing更严格控制的需求集,这既是好事,也是坏事。

您必须做的是让JavaFX代码在它的事件线程中运行。这比听起来更棘手(而且似乎需要),例如.

原色调整(取自JavaDocs实例)

代码语言:javascript
复制
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.effect.ColorAdjust;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.stage.Stage;
import javax.imageio.ImageIO;

public class Test extends Application {

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

    @Override
    public void start(Stage stage) throws Exception {

        try {
            System.out.println("Load image...");
            BufferedImage imagem = ImageIO.read(new File("..."));
            Image image = SwingFXUtils.toFXImage(imagem, null);

            ColorAdjust colorAdjust = new ColorAdjust();
            colorAdjust.setHue(0);
            colorAdjust.setSaturation(-1);
            colorAdjust.setBrightness(0);
            colorAdjust.setContrast(0);
//          colorAdjust.setHue(-0.05);
//          colorAdjust.setSaturation(0.2);
//          colorAdjust.setBrightness(0.1);
//          colorAdjust.setContrast(0.1);

            ImageView imageView = new ImageView(image);
            imageView.setFitWidth(image.getWidth());
            imageView.setPreserveRatio(true);
            imageView.setEffect(colorAdjust);

            System.out.println("Convert and save...");
            imagem = SwingFXUtils.fromFXImage(imageView.snapshot(null, null), null);
            ImageIO.write(imagem, "png", new File("ColorAdjusted.png"));
        } catch (IOException exp) {
            exp.printStackTrace();
        } finally {
            Platform.exit();
        }
    }

}

下一件事是试图找出如何让它作为一个实用工具类工作.

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28755243

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档