2015-02-27 2 views
0

У меня вопрос о настройке контраста, насыщенности и оттенка изображения, загруженного в jXImageView из библиотеки swingx.CollorAdjust с ImageView от SwingX?

У меня есть методы ColorAdjust.

ColorAdjust colorAdjust = new ColorAdjust(); 
colorAdjust.setContrast(0.3); 
colorAdjust.setHue(-0.03); 
colorAdjust.setBrightness(0.2); 
colorAdjust.setSaturation(0.2); 

Когда пользователь нажимает на кнопку «Enhancement», изображение должно немного изменить, но как это сделать? Помните: я использую jXImageView.

я увеличил контраст уже с помощью этого кода:

float brightenFactor = 1.5f; 
    BufferedImage imagem = (BufferedImage) jXImageView2.getImage(); 
    RescaleOp op = new RescaleOp(brightenFactor, 0, null); 
    imagem = op.filter(imagem, imagem); 
    jXImageView2.updateUI(); 

Редактировать

Я tryied:

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); 

... но без успеха.

+0

В то время как вы можете конвертировать 'BufferedImage' в и из' Image', я не если 'ImageView' знать будут применять значения «ColorAdjust» непосредственно к основному «изображению» или если они просто используют их для изменения способа его раскраски. Вы можете начать с просмотра ['SwingFXUtils'] (http://docs.oracle.com/javafx/2/api/javafx/embed/swing/SwingFXUtils.html) для преобразования между двумя форматами изображений – MadProgrammer

+0

Спасибо за совет! –

+0

Ahh, попробуйте [this] (https://gist.github.com/jewelsea/2870355)! – MadProgrammer

ответ

2

Раствор образца

  • Изображение на слева - исходное изображение.
  • Изображение справа - это отрегулированное изображение (которое имеет цвет, ненасыщенный, чтобы сделать изображение монохромным).

adjustedcolors

Это решение работает:

  1. Преобразование Swing/AWT BufferedImage в JavaFX Image.
  2. Использование эффекта JavaFX ColorAdjust для изменения изображения.
  3. A snapshot изображения, настроенного с учетом цвета, для создания нового изображения JavaFX.
  4. Новый образ JavaFX: converted Возврат к новому Swing/AWT BufferedImage.

Поскольку решение смешивает два различных инструментариев, следующие соображения были применены при его создании:

  1. Будьте осторожен импорт, используемый для того, чтобы правильно класс используются для данного инструментария вызова; например, как JavaFX, так и Swing/AWT имеют классы Color и Image, поэтому необходимо обеспечить, чтобы полностью подходящий класс для данного инструментария использовался в правильном контексте - передача Swing-изображения непосредственно в API JavaFX была бы неправильной и порочащей -versa.

  2. Будьте осторожны с правилами нарезки. Снимки сцен JavaFX должны быть сделаны в потоке приложений JavaFX. Выполнение API Swing должно выполняться в потоке отправки событий Swing. Различные утилиты соответствующих наборов инструментов (например, и класс JavaFX Platform) используются для обеспечения соответствия ограничений потоковой передачи данных наборов инструментов.

  3. Инструментарий JavaFX должен быть инициализирован до его использования. Обычно это делается неявно, когда ваше приложение расширяет класс JavaFX Application. Однако приложения Swing не расширяют класс приложений JavaFX. Таким образом, возможно, несколько контр-интуитивно и плохо документировано, необходимо создать экземпляр JFXPanel для инициализации инструментария JavaFX до использования инструментария.

Примечания

  1. Это решение изготовлен в соответствии с конкретными требованиями вопроса (который является свинг приложение, которое необходимо внести некоторые корректировки цвета). Если вы хотите только настроить цвета изображений из JavaFX и не использовать Swing, то существуют more straight-forward solutions и являются предпочтительными.

  2. Вызов System.exit, как правило, достаточно, чтобы закрыть инструментарий JavaFX. Образец приложения вызывает Platform.exit, чтобы явно закрыть инструментарий JavaFX, но в этом случае явный вызов Platform.exit, вероятно, не нужен.

Это означает, что ColorAdjuster в растворе можно использовать из программы свинга без программы свинга явно импортировать любые классы JavaFX (хотя, внутренне, то ColorAdjuster будет импортировать эти классы, и система должна соответствовать нормальному минимуму требования для запуска инструментов Swing и JavaFX).Уменьшение смешивания импорта с одним набором инструментов по классу, где это возможно, желательно, потому что смешивание импорта в одном классе для смешанного приложения JavaFX/Swing является хорошим источником утомительных ошибок из-за потенциальных конфликтов имен и связанных с потоками головных болей.

ColorAdjuster.java

цвет изображения настройки утилиты.

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

Тест Жгут:

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"; 
} 
+0

Теперь, что мне действительно интересно узнать, как это произошло из-за исключения «Toolkit not started», которое я получил, когда попытался использовать 'Platform.runLater'? – MadProgrammer

1

Вы должны преобразовать BufferedImage в javafx.scene.image.Image, вы можете использовать что-то вроде ...

Image image = SwingFXUtils.toFXImage(imagem, null); 

Затем вы можете применить ColorAdjust ...

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); 

Затем преобразовать его обратно ...

imagem = SwingFXUtils.fromFXImage(imageView.snapshot(null, null), null); 

Эта идея украдена у jewelsea/SaveAdjustedImage.java. То, что я не знаю, если ImageView потребности реализовать на экране первый не все ...

Обновлено

Просто так вы знаете, вы скрещивании двух различных механизмов пользовательского интерфейса, как они говорят в фильмах, «не пересекайте потоки!»

JavaFX имеет гораздо более жестко контролируемый набор требований, чем Swing, это и хорошо, и плохо.

Что вы ДОЛЖНЫ делать, это получить код JavaFX для запуска в его потоке событий. Это сложнее, чем кажется (и, кажется, должны быть), к примеру ...

enter image description here

Оригинал | Регулировка цвета (взята из JavaDocs example) | Монохромный ...

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(); 
     } 
    } 

} 

Следующая вещь, которую пытается решить, как вы бы получить эту работу, как утилита класса ...

+0

Прежде всего, я просто хочу сказать огромное спасибо тебе! Но мой код не работает, я редактировал свой пост, чтобы показать, что я пытался. –