Я не знаю, это именно то, что вы ищете, возможно, я не понимаю вашего вопроса. Но вы можете преобразовать цветное изображение в серое, обесцветив цвет с помощью ColorAdjust.
ColorAdjust monochrome = new ColorAdjust();
monochrome.setSaturation(-1);
ImageView gray = new ImageView(new Image(IMAGE_LOC));
gray.setEffect(monochrome);
Я не уверен, почему бедные бабушка и дедушка должны быть выцветшими до черного и белого, но это должно быть так.
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.effect.ColorAdjust;
import javafx.scene.image.*;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class GrayScale extends Application {
@Override
public void start(Stage stage) {
ColorAdjust monochrome = new ColorAdjust();
monochrome.setSaturation(-1);
Image image = new Image(IMAGE_LOC);
ImageView color = new ImageView(image);
ImageView gray = new ImageView(image);
gray.setEffect(monochrome);
HBox layout = new HBox(10, color, gray);
layout.setPadding(new Insets(10));
Scene scene = new Scene(layout);
scene.setFill(Color.BLACK);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
// source: http://www.photoshopessentials.com/photo-editing/black-and-white-tutorials/desaturate/
private static final String IMAGE_LOC =
"http://pe-images.s3.amazonaws.com/photo-effects/black-and-white/grandparents.jpg";
}
Если ColorAdjust не работает для вас, вы можете просто выполнять манипуляции с попиксельной базой, используя PixelReaders и PixelWriters для WritableImage. (Я не вижу причин для использования холста, как вы упоминаете в своем вопросе). Для связанной реализации с использованием WritableImage см.:
Возможно, вы также хотите расширить PixelFormat новым типом и расширить PixelReader для чтения вашего буфера данных, что может быть возможно, хотя я думаю, что это не обязательно для достижения того, что вы хотите:
PixelReader reader = new GrayScalePixelReader();
reader.getPixels(0, 0, W, H,
GrayScalePixelFormat.instance(), grayScaleByteBuffer, 0, scanlineStride);
Image img = new WritableImage(reader, W, H);
где GrayScalePixelReader и GrayScalePixelFormat — это новые классы, которые вы создаете с помощью расширения.
FX поддерживает типы пикселей, определенные PixelFormat, такие как BYTE_BGRA и BYTE_BGRA_PRE; Я хочу добавить поддержку нового типа пикселей, который имеет один образец на пиксель, который представляет собой значение данных без знака 16.
pixelFormat = PixelFormat.createByteIndexedInstance(LUT);
getPixelWriter().setPixels(0, 0, w, h, pixelFormat, normalisedImageData, 0, w);
Да, вы почти можете это сделать, но это немного сложно. Я согласен с тем, что существующий PixelFormat в Java 8 на самом деле не очень легко расширяется пользователем по таким причинам, как вы упомянули:
Некоторые методы, например, getPixelWriter() класса WritabelImage, являются окончательными, поэтому вы даже не можете их переопределить. Инфраструктура образов выглядит так, как будто она не предназначена для такого расширения.
Обычно, когда дело доходит до JavaFX, эта нехватка расширяемости преднамеренно встроена. Некоторые причины:
- Безопасность, чтобы людям было труднее подрывать платформу и делать что-то злонамеренное, переопределяя основные функции, чтобы также выполнять вредоносные побочные эффекты.
- Предоставьте разработчику приложения упрощенный интерфейс, чтобы упростить понимание и использование API.
- Намеренно сделайте некоторые части платформы непрозрачными, чтобы разработчикам библиотек было легче поддерживать реализацию основной библиотеки и изменять ее по своему усмотрению, не затрагивая пользовательские программы.
Конечно, компромиссом (как в данном случае) может быть недостаток гибкости в попытках достичь желаемого.
Если вы посмотрите на реализацию изображения в JavaFX, она состоит из четырех разных компонентов:
- API javafx.scene.image< /а>.
- Реализация платформы (prism) поддержка API изображений (см. источник).
- библиотеки ввода-вывода изображений для чтения распространенных форматов изображений (png, jpg и т. д.).
- Интерфейсы к API графического аппаратного ускорителя или API рендеринга программного обеспечения, например es2, который, в конечном счете, обычно обрабатывает изображение как входную текстуру для аппаратного графического API, такого как OpenGL или Direct3D.
Интересная вещь о форматах пикселей в градациях серого заключается в том, что они не отображаются напрямую в (1) API-интерфейсах javafx.scene.image. Однако реализация платформы prism, библиотеки ввода-вывода изображений и аппаратные ускорители (2, 3 и 4) имеют некоторый уровень встроенной поддержки оттенков серого. Например, файл PNG может иметь формат оттенков серого, и imageIO распознает формат и передаст буфер оттенков серого непосредственно в класс изображения prism для интерпретации.
Буферы оттенков серого также поддерживаются уровнем аппаратного ускорения, как показано на ES2Texture. Таким образом, это дает идеальную ситуацию с буфером, закодированным в формате пикселей в оттенках серого, для изображения, которое может быть напрямую преобразовано в текстуру с аппаратным ускорением. Однако обратите внимание, что текущий формат пикселей для байтового буфера в градациях серого, поддерживаемый системой рендеринга Prism/ES2, предназначен для 8-битной кодировки, а не для 16-битной кодировки, которую вы в идеале просите (хотя комментарии к формату пикселей призмы не говорят о том, что в будущем может понадобиться 16-битный тип ;-):
// L8, A8 types:
// NOTE : we might need L8A8 16-bit type
BYTE_GRAY (DataType.BYTE, 1, true, true),
Таким образом, это означает, что большая часть инфраструктуры, которую вы ищете, которая позволяет напрямую интерпретировать закодированный в градациях серого буфер изображения средой выполнения JavaFX, уже существует, однако она размещена внутри com.sun
классов и частного API и недоступна непосредственно пользователю в общедоступные javafx.scene.image
API.
Можно создать запрос функции, чтобы включить общедоступный API для форматов пикселей в градациях серого, или запросить об этом на странице < href="http://mail.openjdk.java.net/mailman/listinfo/openjfx-dev" rel="nofollow noreferrer">список рассылки openjfx-dev. Кратчайшим сроком реализации таких функций будет Java 10. Похоже, что такой запрос может уже существовать, поэтому вы можете прокомментировать его или добавить в список рассылки openjfx-dev, чтобы помочь продвинуть его вперед:
Помогает ли приведенная выше информация вам в решении вашей текущей проблемы -> вероятно, нет :-) Но, надеюсь, она поможет понять платформу и ее возможности, ограничения и потенциальные механизмы для будущего расширения, чтобы полностью удовлетворить ваши требования.
person
jewelsea
schedule
28.03.2017